1 // Copyright 2012 Intel Corporation
3 // All rights reserved.
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
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
31 // The wrapper must be included before wayland-(client|egl).h
32 #include "wayland_wrapper.h"
33 #include <wayland-egl.h>
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"
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
);
58 ok
&= wegl_surface_teardown(&self
->wegl
);
61 plat
->wl_egl_window_destroy(self
->wl_window
);
63 if (self
->wl_shell_surface
)
64 wl_shell_surface_destroy(self
->wl_shell_surface
);
67 wl_surface_destroy(self
->wl_surface
);
74 shell_surface_listener_ping(void *data
,
75 struct wl_shell_surface
*shell_surface
,
78 wl_shell_surface_pong(shell_surface
, serial
);
82 shell_surface_listener_configure(void *data
,
83 struct wl_shell_surface
*shell_surface
,
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
103 wayland_window_create(struct wcore_platform
*wc_plat
,
104 struct wcore_config
*wc_config
,
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
);
114 if (width
== -1 && height
== -1) {
115 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM
,
116 "fullscreen window not supported");
120 if (wcore_attrib_list_length(attrib_list
) > 0) {
121 wcore_error_bad_attribute(attrib_list
[0]);
125 self
= wcore_calloc(sizeof(*self
));
129 if (!dpy
->wl_compositor
) {
130 wcore_errorf(WAFFLE_ERROR_UNKNOWN
, "wayland compositor not found");
133 if (!dpy
->wl_shell
) {
134 wcore_errorf(WAFFLE_ERROR_UNKNOWN
, "wayland shell not found");
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");
145 self
->wl_shell_surface
= wl_shell_get_shell_surface(dpy
->wl_shell
,
147 if (!self
->wl_shell_surface
) {
148 wcore_errorf(WAFFLE_ERROR_UNKNOWN
,
149 "wl_shell_get_shell_surface failed");
153 wl_shell_surface_add_listener(self
->wl_shell_surface
,
154 &shell_surface_listener
,
157 self
->wl_window
= plat
->wl_egl_window_create(self
->wl_surface
,
159 if (!self
->wl_window
) {
160 wcore_errorf(WAFFLE_ERROR_UNKNOWN
, "wl_egl_window_create failed");
164 ok
= wegl_window_init(&self
->wegl
, wc_config
, (intptr_t) self
->wl_window
);
168 ok
= wayland_display_sync(dpy
);
172 return &self
->wegl
.wcore
;
175 wayland_window_destroy(&self
->wegl
.wcore
);
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
);
187 wl_shell_surface_set_toplevel(self
->wl_shell_surface
);
189 ok
= wayland_display_sync(dpy
);
193 // FIXME: How to detect errors in Wayland?
198 wayland_window_swap_buffers(struct wcore_window
*wc_self
)
200 struct wayland_display
*dpy
= wayland_display(wc_self
->display
);
203 ok
= wegl_surface_swap_buffers(wc_self
);
207 ok
= wayland_display_sync(dpy
);
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
))
229 // FIXME: How to detect if the resize failed?
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
);
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
;