gbm: factor out gbm_window_{init,teardown}
[mesa-waffle.git] / src / waffle / wayland / wayland_window.c
blob89f7342759c1d025d06c1311f9e24a142d709bf8
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|egl).h
32 #include "wayland_wrapper.h"
33 #include <wayland-egl.h>
34 #undef container_of
36 #include "waffle_wayland.h"
38 #include "wcore_attrib_list.h"
39 #include "wcore_error.h"
41 #include "wegl_config.h"
43 #include "wayland_display.h"
44 #include "wayland_platform.h"
45 #include "wayland_window.h"
47 bool
48 wayland_window_destroy(struct wcore_window *wc_self)
50 struct wcore_platform *wc_plat = wc_self->display->platform;
51 struct wayland_platform *plat = wayland_platform(wegl_platform(wc_plat));
52 struct wayland_window *self = wayland_window(wc_self);
53 bool ok = true;
55 if (!self)
56 return ok;
58 ok &= wegl_surface_teardown(&self->wegl);
60 if (self->wl_window)
61 plat->wl_egl_window_destroy(self->wl_window);
63 if (self->wl_shell_surface)
64 wl_shell_surface_destroy(self->wl_shell_surface);
66 if (self->wl_surface)
67 wl_surface_destroy(self->wl_surface);
69 free(self);
70 return ok;
73 static void
74 shell_surface_listener_ping(void *data,
75 struct wl_shell_surface *shell_surface,
76 uint32_t serial)
78 wl_shell_surface_pong(shell_surface, serial);
81 static void
82 shell_surface_listener_configure(void *data,
83 struct wl_shell_surface *shell_surface,
84 uint32_t edges,
85 int32_t width,
86 int32_t height)
90 static void
91 shell_surface_listener_popup_done(void *data,
92 struct wl_shell_surface *shell_surface)
96 static const struct wl_shell_surface_listener shell_surface_listener = {
97 .ping = shell_surface_listener_ping,
98 .configure = shell_surface_listener_configure,
99 .popup_done = shell_surface_listener_popup_done
102 struct wcore_window*
103 wayland_window_create(struct wcore_platform *wc_plat,
104 struct wcore_config *wc_config,
105 int32_t width,
106 int32_t height,
107 const intptr_t attrib_list[])
109 struct wayland_window *self;
110 struct wayland_platform *plat = wayland_platform(wegl_platform(wc_plat));
111 struct wayland_display *dpy = wayland_display(wc_config->display);
112 bool ok = true;
114 if (width == -1 && height == -1) {
115 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
116 "fullscreen window not supported");
117 return NULL;
120 if (wcore_attrib_list_length(attrib_list) > 0) {
121 wcore_error_bad_attribute(attrib_list[0]);
122 return NULL;
125 self = wcore_calloc(sizeof(*self));
126 if (self == NULL)
127 return NULL;
129 if (!dpy->wl_compositor) {
130 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "wayland compositor not found");
131 goto error;
133 if (!dpy->wl_shell) {
134 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "wayland shell not found");
135 goto error;
138 self->wl_surface = wl_compositor_create_surface(dpy->wl_compositor);
139 if (!self->wl_surface) {
140 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
141 "wl_compositor_create_surface failed");
142 goto error;
145 self->wl_shell_surface = wl_shell_get_shell_surface(dpy->wl_shell,
146 self->wl_surface);
147 if (!self->wl_shell_surface) {
148 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
149 "wl_shell_get_shell_surface failed");
150 goto error;
153 wl_shell_surface_add_listener(self->wl_shell_surface,
154 &shell_surface_listener,
155 NULL);
157 self->wl_window = plat->wl_egl_window_create(self->wl_surface,
158 width, height);
159 if (!self->wl_window) {
160 wcore_errorf(WAFFLE_ERROR_UNKNOWN, "wl_egl_window_create failed");
161 goto error;
164 ok = wegl_window_init(&self->wegl, wc_config, (intptr_t) self->wl_window);
165 if (!ok)
166 goto error;
168 ok = wayland_display_sync(dpy);
169 if (!ok)
170 goto error;
172 return &self->wegl.wcore;
174 error:
175 wayland_window_destroy(&self->wegl.wcore);
176 return NULL;
180 bool
181 wayland_window_show(struct wcore_window *wc_self)
183 struct wayland_window *self = wayland_window(wc_self);
184 struct wayland_display *dpy = wayland_display(wc_self->display);
185 bool ok = true;
187 wl_shell_surface_set_toplevel(self->wl_shell_surface);
189 ok = wayland_display_sync(dpy);
190 if (!ok)
191 return false;
193 // FIXME: How to detect errors in Wayland?
194 return true;
197 bool
198 wayland_window_swap_buffers(struct wcore_window *wc_self)
200 struct wayland_display *dpy = wayland_display(wc_self->display);
201 bool ok;
203 ok = wegl_surface_swap_buffers(wc_self);
204 if (!ok)
205 return false;
207 ok = wayland_display_sync(dpy);
208 if (!ok)
209 return false;
211 return true;
214 bool
215 wayland_window_resize(struct wcore_window *wc_self,
216 int32_t width, int32_t height)
218 struct wayland_window *self = wayland_window(wc_self);
219 struct wcore_platform *wc_plat = wc_self->display->platform;
220 struct wayland_platform *plat = wayland_platform(wegl_platform(wc_plat));
221 struct wayland_display *dpy = wayland_display(self->wegl.wcore.display);
223 plat->wl_egl_window_resize(wayland_window(wc_self)->wl_window,
224 width, height, 0, 0);
226 if (!wayland_display_sync(dpy))
227 return false;
229 // FIXME: How to detect if the resize failed?
230 return true;
233 union waffle_native_window*
234 wayland_window_get_native(struct wcore_window *wc_self)
236 struct wayland_window *self = wayland_window(wc_self);
237 struct wayland_display *dpy = wayland_display(wc_self->display);
238 union waffle_native_window *n_window;
240 WCORE_CREATE_NATIVE_UNION(n_window, wayland);
241 if (!n_window)
242 return NULL;
244 wayland_display_fill_native(dpy, &n_window->wayland->display);
245 n_window->wayland->wl_surface = self->wl_surface;
246 n_window->wayland->wl_shell_surface = self->wl_shell_surface;
247 n_window->wayland->wl_window = self->wl_window;
248 n_window->wayland->egl_surface = self->wegl.egl;
250 return n_window;