[PATCH 2/3] wayland-client: Introduce shm pool helper function

Andre Heider a.heider at gmail.com
Sat Aug 4 06:22:54 PDT 2012


Every client dealing with shm buffers requires code to set up pools.
Wayland already implements this platform independent, so make public
helper function available instead of putting the burden on every client.
---
 src/Makefile.am      |    6 ++-
 src/wayland-client.c |  110 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/wayland-client.h |   23 +++++++++++
 3 files changed, 138 insertions(+), 1 deletion(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index f93954e..616a89f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,7 +26,11 @@ libwayland_server_la_SOURCES =			\
 	data-device.c				\
 	event-loop.c
 
-libwayland_client_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt -lm
+libwayland_client_la_LIBADD =			\
+	$(FFI_LIBS)				\
+	libwayland-util.la			\
+	../shared/libshared.la			\
+	-lrt -lm
 libwayland_client_la_SOURCES =			\
 	wayland-protocol.c			\
 	wayland-client.c
diff --git a/src/wayland-client.c b/src/wayland-client.c
index 631ec5a..569501d 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -28,6 +28,7 @@
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/mman.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <ctype.h>
@@ -39,6 +40,7 @@
 #include "wayland-os.h"
 #include "wayland-client.h"
 #include "wayland-private.h"
+#include "../shared/os-compatibility.h"
 
 struct wl_global_listener {
 	wl_display_global_func_t handler;
@@ -75,6 +77,14 @@ struct wl_display {
 	void *global_handler_data;
 };
 
+struct wl_shm_pool_helper {
+	struct wl_shm_pool *pool;
+	int fd;
+	int32_t size;
+	int32_t used;
+	void *data;
+};
+
 static int wl_debug = 0;
 
 static int
@@ -643,3 +653,103 @@ wl_log_set_handler_client(wl_log_func_t handler)
 {
 	wl_log_handler = handler;
 }
+
+WL_EXPORT struct wl_shm_pool_helper *
+wl_shm_pool_helper_create(struct wl_shm *shm, int32_t size)
+{
+	struct wl_shm_pool_helper *pool;
+
+	pool = malloc(sizeof *pool);
+	if (!pool)
+		return NULL;
+
+	pool->fd = os_create_anonymous_file(size);
+	if (pool->fd < 0)
+		goto err_free;
+
+	pool->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
+			  pool->fd, 0);
+
+	if (pool->data == MAP_FAILED)
+		goto err_close;
+
+	pool->pool = wl_shm_create_pool(shm, pool->fd, size);
+	pool->size = size;
+	pool->used = 0;
+
+	return pool;
+
+err_close:
+	close(pool->fd);
+err_free:
+	free(pool);
+	return NULL;
+}
+
+WL_EXPORT int
+wl_shm_pool_helper_resize(struct wl_shm_pool_helper *pool, int32_t size)
+{
+	if (ftruncate(pool->fd, size) < 0)
+		return 0;
+
+	wl_shm_pool_resize(pool->pool, size);
+
+	munmap(pool->data, pool->size);
+
+	pool->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
+			  pool->fd, 0);
+	pool->size = size;
+
+	return 1;
+}
+
+WL_EXPORT void *
+wl_shm_pool_helper_allocate(struct wl_shm_pool_helper *pool, int32_t size,
+			    int32_t *offset)
+{
+	void *p;
+
+	if (pool->used + size > pool->size) {
+		if (offset)
+			*offset = 0;
+
+		return NULL;
+	}
+
+	if (offset)
+		*offset = pool->used;
+
+	p = (char *) pool->data + pool->used;
+	pool->used += size;
+
+	return p;
+}
+
+WL_EXPORT void
+wl_shm_pool_helper_reset(struct wl_shm_pool_helper *pool)
+{
+	pool->used = 0;
+}
+
+WL_EXPORT struct wl_shm_pool *
+wl_shm_pool_helper_get_pool(struct wl_shm_pool_helper *pool)
+{
+	return pool->pool;
+}
+
+WL_EXPORT int32_t
+wl_shm_pool_helper_get_size(struct wl_shm_pool_helper *pool)
+{
+	return pool->size;
+}
+
+WL_EXPORT void
+wl_shm_pool_helper_destroy(struct wl_shm_pool_helper *pool, int32_t unmap)
+{
+	if (unmap)
+		munmap(pool->data, pool->size);
+
+	wl_shm_pool_destroy(pool->pool);
+	close(pool->fd);
+	free(pool);
+}
diff --git a/src/wayland-client.h b/src/wayland-client.h
index 06dc6fe..2a6e869 100644
--- a/src/wayland-client.h
+++ b/src/wayland-client.h
@@ -32,6 +32,7 @@ extern "C" {
 
 struct wl_proxy;
 struct wl_display;
+struct wl_shm_pool_helper;
 
 void wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);
 struct wl_proxy *wl_proxy_create(struct wl_proxy *factory,
@@ -98,6 +99,28 @@ wl_display_get_global(struct wl_display *display,
 
 void wl_log_set_handler_client(wl_log_func_t handler);
 
+struct wl_shm_pool_helper *
+wl_shm_pool_helper_create(struct wl_shm *shm, int32_t size);
+
+int
+wl_shm_pool_helper_resize(struct wl_shm_pool_helper *pool, int32_t size);
+
+void *
+wl_shm_pool_helper_allocate(struct wl_shm_pool_helper *pool, int32_t size,
+			    int32_t *offset);
+
+void
+wl_shm_pool_helper_reset(struct wl_shm_pool_helper *pool);
+
+struct wl_shm_pool *
+wl_shm_pool_helper_get_pool(struct wl_shm_pool_helper *pool);
+
+int32_t
+wl_shm_pool_helper_get_size(struct wl_shm_pool_helper *pool);
+
+void
+wl_shm_pool_helper_destroy(struct wl_shm_pool_helper *pool, int32_t unmap);
+
 #ifdef  __cplusplus
 }
 #endif
-- 
1.7.10.4



More information about the wayland-devel mailing list