enlightenment/src/bin/e_wayland/e_buffer.c

92 lines
2.4 KiB
C

#include "e.h"
/* local function prototypes */
static void _e_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED);
static void _e_buffer_reference_cb_destroy(struct wl_listener *listener, void *data);
EAPI E_Buffer *
e_buffer_resource_get(struct wl_resource *resource)
{
E_Buffer *buffer;
struct wl_listener *listener;
listener = wl_resource_get_destroy_listener(resource, _e_buffer_cb_destroy);
if (listener)
buffer = container_of(listener, E_Buffer, buffer_destroy);
else
{
if (!(buffer = E_NEW_RAW(E_Buffer, 1)))
return NULL;
buffer->wl.resource = resource;
wl_signal_init(&buffer->signals.destroy);
buffer->buffer_destroy.notify = _e_buffer_cb_destroy;
wl_resource_add_destroy_listener(resource, &buffer->buffer_destroy);
}
return buffer;
}
EAPI void
e_buffer_reference(E_Buffer_Reference *br, E_Buffer *buffer)
{
/* check for valid buffer reference */
if (!br) return;
/* check if the new buffer is difference than the one we already have
* referenced */
if ((br->buffer) && (br->buffer != buffer))
{
br->buffer->busy_count--;
if (br->buffer->busy_count == 0)
{
/* queue a release event */
wl_resource_queue_event(br->buffer->wl.resource,
WL_BUFFER_RELEASE);
}
/* remove any existing destroy listener */
wl_list_remove(&br->buffer_destroy.link);
}
/* if we have a valid buffer, reference it */
if ((buffer) && (br->buffer != buffer))
{
buffer->busy_count++;
/* setup destroy listener */
wl_signal_add(&buffer->signals.destroy, &br->buffer_destroy);
}
br->buffer = buffer;
br->buffer_destroy.notify = _e_buffer_reference_cb_destroy;
}
/* local functions */
static void
_e_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
{
E_Buffer *buffer;
/* try to get the buffer_reference structure from the listener */
if (!(buffer = container_of(listener, E_Buffer, buffer_destroy)))
return;
wl_signal_emit(&buffer->signals.destroy, buffer);
E_FREE(buffer);
}
static void
_e_buffer_reference_cb_destroy(struct wl_listener *listener, void *data)
{
E_Buffer_Reference *br;
if (!(br = container_of(listener, E_Buffer_Reference, buffer_destroy)))
return;
if ((E_Buffer *)data != br->buffer) return;
br->buffer = NULL;
}