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) \