#ifdef HAVE_CONFIG_H # include #endif #include "ecore_wl2_private.h" #include #include static Eina_List *_smanagers = NULL; static int _smanager_count = 0; EAPI void ecore_wl2_surface_destroy(Ecore_Wl2_Surface *surface) { EINA_SAFETY_ON_NULL_RETURN(surface); ecore_event_handler_del(surface->offscreen_handler); surface->funcs->destroy(surface, surface->private_data); surface->wl2_win->wl2_surface = NULL; surface->wl2_win = NULL; free(surface); /* We took a reference to ecore_wl2 in surface create to prevent * modules unloading with surfaces in flight. Release that now. */ ecore_wl2_shutdown(); } EAPI void ecore_wl2_surface_reconfigure(Ecore_Wl2_Surface *surface, int w, int h, uint32_t flags, Eina_Bool alpha) { EINA_SAFETY_ON_NULL_RETURN(surface); surface->funcs->reconfigure(surface, surface->private_data, w, h, flags, alpha); surface->w = w; surface->h = h; surface->alpha = alpha; } EAPI void * ecore_wl2_surface_data_get(Ecore_Wl2_Surface *surface, int *w, int *h) { EINA_SAFETY_ON_NULL_RETURN_VAL(surface, NULL); return surface->funcs->data_get(surface, surface->private_data, w, h); } EAPI int ecore_wl2_surface_assign(Ecore_Wl2_Surface *surface) { EINA_SAFETY_ON_NULL_RETURN_VAL(surface, 0); return surface->funcs->assign(surface, surface->private_data); } EAPI void ecore_wl2_surface_post(Ecore_Wl2_Surface *surface, Eina_Rectangle *rects, unsigned int count) { EINA_SAFETY_ON_NULL_RETURN(surface); surface->funcs->post(surface, surface->private_data, rects, count); } EAPI void ecore_wl2_surface_flush(Ecore_Wl2_Surface *surface, Eina_Bool purge) { EINA_SAFETY_ON_NULL_RETURN(surface); surface->funcs->flush(surface, surface->private_data, purge); } static Eina_Bool _ecore_wl2_surface_cb_offscreen(void *data, int type EINA_UNUSED, void *event) { Ecore_Wl2_Event_Window_Offscreen *ev = event; Ecore_Wl2_Surface *surf = data; if (surf->wl2_win == ev->win) ecore_wl2_surface_flush(surf, EINA_FALSE); return ECORE_CALLBACK_RENEW; } EAPI Ecore_Wl2_Surface * ecore_wl2_surface_create(Ecore_Wl2_Window *win, Eina_Bool alpha) { Ecore_Wl2_Surface *out; Eina_List *l; Ecore_Wl2_Surface_Interface *intf; EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(_smanagers, NULL); if (win->wl2_surface) return win->wl2_surface; out = calloc(1, sizeof(*out)); if (!out) return NULL; out->wl2_win = win; out->alpha = alpha; out->w = 0; out->h = 0; EINA_LIST_FOREACH(_smanagers, l, intf) { out->private_data = intf->setup(win); if (out->private_data) { out->funcs = intf; win->wl2_surface = out; out->offscreen_handler = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_OFFSCREEN, _ecore_wl2_surface_cb_offscreen, out); /* Since we have loadable modules, we need to make sure this * surface keeps ecore_wl2 from de-initting and dlclose()ing * things until after it's destroyed */ ecore_wl2_init(); return out; } } free(out); return NULL; } EAPI Ecore_Wl2_Buffer * ecore_wl2_surface_buffer_create(Ecore_Wl2_Surface *surface) { Ecore_Wl2_Display *ewd; EINA_SAFETY_ON_NULL_RETURN_VAL(surface, NULL); ewd = ecore_wl2_window_display_get(surface->wl2_win); EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL); return ecore_wl2_buffer_create(ewd, surface->w, surface->h, surface->alpha); } EAPI int ecore_wl2_surface_manager_add(Ecore_Wl2_Surface_Interface *intf) { if (intf->version < ECORE_WL2_SURFACE_INTERFACE_VERSION) return 0; _smanagers = eina_list_prepend(_smanagers, intf); intf->id = ++_smanager_count; return intf->id; } EAPI void ecore_wl2_surface_manager_del(Ecore_Wl2_Surface_Interface *intf) { _smanagers = eina_list_remove(_smanagers, intf); } EAPI Ecore_Wl2_Window * ecore_wl2_surface_window_get(Ecore_Wl2_Surface *surface) { EINA_SAFETY_ON_NULL_RETURN_VAL(surface, NULL); return surface->wl2_win; } EAPI Eina_Bool ecore_wl2_surface_alpha_get(Ecore_Wl2_Surface *surface) { EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE); return surface->alpha; }