wayland: resolve wayland-client symbols at runtime (via libdl)
[mesa-waffle.git] / src / waffle / wayland / wayland_display.c
blobe2d59a8e61f9bbc31fbe1c0e30f48d6fcfc24cd2
1 // Copyright 2012 Intel Corporation
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // - Redistributions of source code must retain the above copyright notice, this
9 // list of conditions and the following disclaimer.
11 // - Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #define WL_EGL_PLATFORM 1
28 #include <stdlib.h>
29 #include <string.h>
31 // The wrapper must be included before wayland-client.h
32 #include "wayland_wrapper.h"
33 #include <wayland-client.h>
34 #undef container_of
36 #include "wcore_error.h"
37 #include "wcore_display.h"
39 #include "wegl_display.h"
41 #include "wayland_display.h"
42 #include "wayland_platform.h"
44 bool
45 wayland_display_destroy(struct wcore_display *wc_self)
47 struct wayland_display *self = wayland_display(wc_self);
48 bool ok = true;
50 if (!self)
51 return ok;
53 ok &= wegl_display_teardown(&self->wegl);
55 if (self->wl_display)
56 wl_display_disconnect(self->wl_display);
58 free(self);
59 return ok;
62 static void
63 registry_listener_global(void *data,
64 struct wl_registry *registry,
65 uint32_t name,
66 const char *interface,
67 uint32_t version)
69 struct wayland_display *self = data;
71 if (!strncmp(interface, "wl_compositor", 14)) {
72 self->wl_compositor = wl_registry_bind(self->wl_registry, name,
73 &wl_compositor_interface, 1);
75 else if (!strncmp(interface, "wl_shell", 9)) {
76 self->wl_shell = wl_registry_bind(self->wl_registry, name,
77 &wl_shell_interface, 1);
81 static void
82 registry_listener_global_remove(void *data,
83 struct wl_registry *registry,
84 uint32_t name)
88 static const struct wl_registry_listener registry_listener = {
89 .global = registry_listener_global,
90 .global_remove = registry_listener_global_remove
93 struct wcore_display*
94 wayland_display_connect(struct wcore_platform *wc_plat,
95 const char *name)
97 struct wayland_display *self;
98 bool ok = true;
99 int error = 0;
101 self = wcore_calloc(sizeof(*self));
102 if (self == NULL)
103 return NULL;
105 self->wl_display = wl_display_connect(name);
106 if (!self->wl_display) {
107 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "wl_display_connect failed");
108 goto error;
111 self->wl_registry = wl_display_get_registry(self->wl_display);
112 if (!self->wl_registry) {
113 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "wl_display_get_registry failed");
114 goto error;
117 error = wl_registry_add_listener(self->wl_registry,
118 &registry_listener,
119 self);
120 if (error < 0) {
121 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "wl_registry_add_listener failed");
122 goto error;
125 // Block until the Wayland server has processed all pending requests and
126 // has sent out pending events on all event queues. This should ensure
127 // that the registry listener has received announcement of the shell and
128 // compositor.
129 ok = wayland_display_sync(self);
130 if (!ok)
131 goto error;
133 if (!self->wl_compositor) {
134 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "failed to bind to the wayland "
135 "compositor");
136 goto error;
139 if (!self->wl_shell) {
140 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "failed to bind to the wayland "
141 "shell");
142 goto error;
145 ok = wegl_display_init(&self->wegl, wc_plat, (intptr_t) self->wl_display);
146 if (!ok)
147 goto error;
149 return &self->wegl.wcore;
151 error:
152 wayland_display_destroy(&self->wegl.wcore);
153 return NULL;
156 void
157 wayland_display_fill_native(struct wayland_display *self,
158 struct waffle_wayland_display *n_dpy)
160 n_dpy->wl_display = self->wl_display;
161 n_dpy->wl_compositor = self->wl_compositor;
162 n_dpy->wl_shell = self->wl_shell;
163 n_dpy->egl_display = self->wegl.egl;
166 union waffle_native_display*
167 wayland_display_get_native(struct wcore_display *wc_self)
169 struct wayland_display *self = wayland_display(wc_self);
170 union waffle_native_display *n_dpy;
172 WCORE_CREATE_NATIVE_UNION(n_dpy, wayland);
173 if (!n_dpy)
174 return NULL;
176 wayland_display_fill_native(self, n_dpy->wayland);
178 return n_dpy;
181 bool
182 wayland_display_sync(struct wayland_display *dpy)
184 if (wl_display_roundtrip(dpy->wl_display) == -1) {
185 wcore_error_errno("error on wl_display");
186 return false;
189 return true;