efl/src/lib/ecore_wl2/ecore_wl2_surface.c

174 lines
4.3 KiB
C

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ecore_wl2_private.h"
#include <sys/types.h>
#include <sys/stat.h>
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;
}