off_t offset;
};
+struct ds_buffer_resource_interface
+{
+ const char *name;
+ bool (*is_instance)(struct wl_resource *resource);
+ struct ds_buffer *(*from_resource)(struct wl_resource *resource);
+};
+
struct ds_buffer *
ds_buffer_from_resource(struct wl_resource *resource);
void
ds_buffer_end_data_ptr_access(struct ds_buffer *buffer);
+void
+ds_buffer_register_resource_interface(
+ const struct ds_buffer_resource_interface *iface);
+
#ifdef __cplusplus
}
#endif
#include "libds/log.h"
#include "libds/interfaces/buffer.h"
+static struct wl_array buffer_resource_interfaces = {0};
+
static void buffer_consider_destroy(struct ds_buffer *buffer);
static bool ds_resource_is_buffer(struct wl_resource *resource);
+static const struct ds_buffer_resource_interface *
+get_buffer_resource_iface(struct wl_resource *resource);
WL_EXPORT void
ds_buffer_init(struct ds_buffer *buffer, const struct ds_buffer_interface *iface,
ds_buffer_from_resource(struct wl_resource *resource)
{
struct ds_buffer *buffer;
+ const struct ds_buffer_resource_interface *iface;
assert(resource && ds_resource_is_buffer(resource));
buffer = ds_buffer_lock(&shm_client_buffer->base);
}
else {
- // TODO;
- buffer = NULL;
+ iface = get_buffer_resource_iface(resource);
+ if (!iface) {
+ ds_err("Unknown buffer type");
+ return NULL;
+ }
+
+ buffer = iface->from_resource(resource);
+ if (!buffer) {
+ ds_err("Failed to create %s buffer", iface->name);
+ return NULL;
+ }
+
+ buffer = ds_buffer_lock(buffer);
}
return buffer;
*out_height = buffer->height;
}
+WL_EXPORT void
+ds_buffer_register_resource_interface(
+ const struct ds_buffer_resource_interface *iface)
+{
+ const struct ds_buffer_resource_interface **iface_ptr;
+
+ assert(iface);
+ assert(iface->is_instance);
+ assert(iface->from_resource);
+
+ wl_array_for_each(iface_ptr, &buffer_resource_interfaces) {
+ if (*iface_ptr == iface) {
+ ds_dbg("ds_buffer_resource_interface %s has already "
+ "been registered", iface->name);
+ return;
+ }
+ }
+
+ iface_ptr = wl_array_add(&buffer_resource_interfaces, sizeof(iface));
+ *iface_ptr = iface;
+}
+
static void
buffer_consider_destroy(struct ds_buffer *buffer)
{
return strcmp(wl_resource_get_class(resource),
wl_buffer_interface.name) == 0;
}
+
+static const struct ds_buffer_resource_interface *
+get_buffer_resource_iface(struct wl_resource *resource)
+{
+ struct ds_buffer_resource_interface **iface_ptr;
+
+ wl_array_for_each(iface_ptr, &buffer_resource_interfaces) {
+ if ((*iface_ptr)->is_instance(resource)) {
+ return *iface_ptr;
+ }
+ }
+
+ return NULL;
+}