commit 8d41327

Michael Forney  ·  2014-01-15 22:36:37 +0000 UTC
parent 182f6d3
wayland: Add surfaces
6 files changed,  +113, -4
+1, -0
1@@ -90,6 +90,7 @@ struct wld_context * wld_wayland_drm_create_context(struct wl_display * display,
2         goto error0;
3 
4     context_initialize(&context->base.base, &context_impl);
5+    context->base.display = display;
6     context->base.queue = queue;
7     context->wl = NULL;
8     context->fd = -1;
+1, -0
1@@ -39,6 +39,7 @@ struct wld_wayland_interface
2 struct wayland_context
3 {
4     struct wld_context base;
5+    struct wl_display * display;
6     struct wl_event_queue * queue;
7 };
8 
+1, -0
1@@ -99,6 +99,7 @@ struct wld_context * wld_wayland_shm_create_context
2         goto error0;
3 
4     context_initialize(&context->base.base, &context_impl);
5+    context->base.display = display;
6     context->base.queue = queue;
7     context->wl = NULL;
8     wl_array_init(&context->formats);
+102, -0
  1@@ -34,9 +34,32 @@ struct wayland_exporter
  2     struct wl_buffer * buffer;
  3 };
  4 
  5+struct wayland_buffer_socket
  6+{
  7+    struct wld_buffer_socket base;
  8+    struct wl_buffer_listener listener;
  9+    struct wld_surface * surface;
 10+    struct wl_surface * wl;
 11+    struct wl_display * display;
 12+    struct wl_event_queue * queue;
 13+};
 14+
 15 #include "interface/exporter.h"
 16 IMPL(wayland, exporter)
 17 
 18+static bool buffer_socket_attach(struct wld_buffer_socket * socket,
 19+                                 struct wld_buffer * buffer);
 20+static void buffer_socket_process(struct wld_buffer_socket * socket);
 21+static void buffer_socket_destroy(struct wld_buffer_socket * socket);
 22+
 23+static const struct wld_buffer_socket_impl buffer_socket_impl = {
 24+    .attach = &buffer_socket_attach,
 25+    .process = &buffer_socket_process,
 26+    .destroy = &buffer_socket_destroy
 27+};
 28+
 29+IMPL(wayland, buffer_socket)
 30+
 31 static void sync_done(void * data, struct wl_callback * callback,
 32                       uint32_t msecs);
 33 
 34@@ -44,6 +67,8 @@ static const struct wl_callback_listener sync_listener = {
 35     .done = &sync_done
 36 };
 37 
 38+static void buffer_release(void * data, struct wl_buffer * buffer);
 39+
 40 const static struct wld_wayland_interface * interfaces[] = {
 41 #if WITH_WAYLAND_DRM
 42     [WLD_DRM] = &wayland_drm_interface,
 43@@ -130,6 +155,36 @@ struct wld_context * wld_wayland_create_context
 44     return context;
 45 }
 46 
 47+EXPORT
 48+struct wld_surface * wld_wayland_create_surface(struct wld_context * context,
 49+                                                uint32_t width, uint32_t height,
 50+                                                uint32_t format,
 51+                                                struct wl_surface * wl)
 52+{
 53+    struct wayland_buffer_socket * socket;
 54+
 55+    if (!(socket = malloc(sizeof *socket)))
 56+        goto error0;
 57+
 58+    socket->base.impl = &buffer_socket_impl;
 59+    socket->listener.release = &buffer_release;
 60+    socket->wl = wl;
 61+    socket->queue = ((struct wayland_context *) context)->queue;
 62+    socket->display = ((struct wayland_context *) context)->display;
 63+    socket->surface = buffered_surface_create(context, width, height, format,
 64+                                              &socket->base);
 65+
 66+    if (!socket->surface)
 67+        goto error1;
 68+
 69+    return socket->surface;
 70+
 71+  error1:
 72+    free(socket);
 73+  error0:
 74+    return NULL;
 75+}
 76+
 77 int wayland_roundtrip(struct wl_display * display,
 78                       struct wl_event_queue * queue)
 79 {
 80@@ -185,6 +240,42 @@ void exporter_destroy(struct wld_exporter * base)
 81     free(exporter);
 82 }
 83 
 84+bool buffer_socket_attach(struct wld_buffer_socket * base,
 85+                          struct wld_buffer * buffer)
 86+{
 87+    struct wayland_buffer_socket * socket = wayland_buffer_socket(base);
 88+    struct wl_buffer * wl;
 89+    union wld_object object;
 90+
 91+    if (!wld_export(buffer, WLD_WAYLAND_OBJECT_BUFFER, &object))
 92+        return false;
 93+
 94+    wl = object.ptr;
 95+
 96+    if (!wl_proxy_get_listener((struct wl_proxy *) wl))
 97+        wl_buffer_add_listener(wl, &socket->listener, buffer);
 98+
 99+    wl_surface_attach(socket->wl, wl, 0, 0);
100+    wl_surface_commit(socket->wl);
101+
102+    return true;
103+}
104+
105+void buffer_socket_process(struct wld_buffer_socket * base)
106+{
107+    struct wayland_buffer_socket * socket = wayland_buffer_socket(base);
108+
109+    /* Since events for our wl_buffers lie in a special queue used by WLD, we
110+     * must dispatch these events here so that we see any release events before
111+     * the next back buffer is chosen. */
112+    wl_display_dispatch_queue_pending(socket->display, socket->queue);
113+}
114+
115+void buffer_socket_destroy(struct wld_buffer_socket * socket)
116+{
117+    free(socket);
118+}
119+
120 void sync_done(void * data, struct wl_callback * callback, uint32_t msecs)
121 {
122     bool * done = data;
123@@ -193,3 +284,14 @@ void sync_done(void * data, struct wl_callback * callback, uint32_t msecs)
124     wl_callback_destroy(callback);
125 }
126 
127+void buffer_release(void * data, struct wl_buffer * wl)
128+{
129+    struct wld_buffer * buffer = data;
130+    const struct wl_buffer_listener * listener
131+        = wl_proxy_get_listener((struct wl_proxy *) wl);
132+    struct wayland_buffer_socket * socket
133+        = CONTAINER_OF(listener, struct wayland_buffer_socket, listener);
134+
135+    wld_surface_release(socket->surface, buffer);
136+}
137+
+6, -0
 1@@ -27,6 +27,7 @@
 2 #include <stdint.h>
 3 
 4 struct wl_display;
 5+struct wl_surface;
 6 
 7 enum wld_wayland_interface_id
 8 {
 9@@ -64,5 +65,10 @@ enum wld_wayland_object_type
10 struct wld_context * wld_wayland_create_context
11     (struct wl_display * display, enum wld_wayland_interface_id id, ...);
12 
13+struct wld_surface * wld_wayland_create_surface(struct wld_context * context,
14+                                                uint32_t width, uint32_t height,
15+                                                uint32_t format,
16+                                                struct wl_surface * surface);
17+
18 #endif
19 
+2, -4
 1@@ -33,10 +33,6 @@
 2 #include FT_FREETYPE_H
 3 #include FT_BITMAP_H
 4 
 5-#ifndef offsetof
 6-#   define offsetof __builtin_offsetof
 7-#endif
 8-
 9 #define ARRAY_LENGTH(array) (sizeof (array) / sizeof (array)[0])
10 #if ENABLE_DEBUG
11 #   define DEBUG(format, ...) \
12@@ -46,6 +42,8 @@
13 #endif
14 
15 #define EXPORT __attribute__((visibility("default")))
16+#define CONTAINER_OF(ptr, type, member) \
17+    ((type *)((uintptr_t) ptr - offsetof(type, member)))
18 #define IMPL(name, type)                                                    \
19     static inline struct name ## _ ## type * name ## _ ## type              \
20         (struct wld_ ## type * type)                                        \