1 /*
2 * Copyright © 2015 Collabora, Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26 #ifndef WESTON_PLATFORM_H
27 #define WESTON_PLATFORM_H
28
29 #include <stdbool.h>
30 #include <string.h>
31
32 #ifdef ENABLE_EGL
33 #include <wayland-egl.h>
34 #include <EGL/egl.h>
35 #include <EGL/eglext.h>
36
37 #include "weston-egl-ext.h"
38 #endif
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 #ifdef ENABLE_EGL
45
46 static bool
weston_check_egl_extension(const char * extensions,const char * extension)47 weston_check_egl_extension(const char *extensions, const char *extension)
48 {
49 size_t extlen = strlen(extension);
50 const char *end = extensions + strlen(extensions);
51
52 while (extensions < end) {
53 size_t n = 0;
54
55 /* Skip whitespaces, if any */
56 if (*extensions == ' ') {
57 extensions++;
58 continue;
59 }
60
61 n = strcspn(extensions, " ");
62
63 /* Compare strings */
64 if (n == extlen && strncmp(extension, extensions, n) == 0)
65 return true; /* Found */
66
67 extensions += n;
68 }
69
70 /* Not found */
71 return false;
72 }
73
74 static inline void *
weston_platform_get_egl_proc_address(const char * address)75 weston_platform_get_egl_proc_address(const char *address)
76 {
77 const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
78
79 if (extensions &&
80 (weston_check_egl_extension(extensions, "EGL_EXT_platform_wayland") ||
81 weston_check_egl_extension(extensions, "EGL_KHR_platform_wayland"))) {
82 return (void *) eglGetProcAddress(address);
83 }
84
85 return NULL;
86 }
87
88 static inline EGLDisplay
weston_platform_get_egl_display(EGLenum platform,void * native_display,const EGLint * attrib_list)89 weston_platform_get_egl_display(EGLenum platform, void *native_display,
90 const EGLint *attrib_list)
91 {
92 static PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL;
93
94 if (!get_platform_display) {
95 get_platform_display = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
96 weston_platform_get_egl_proc_address(
97 "eglGetPlatformDisplayEXT");
98 }
99
100 if (get_platform_display)
101 return get_platform_display(platform,
102 native_display, attrib_list);
103
104 return eglGetDisplay((EGLNativeDisplayType) native_display);
105 }
106
107 static inline EGLSurface
weston_platform_create_egl_surface(EGLDisplay dpy,EGLConfig config,void * native_window,const EGLint * attrib_list)108 weston_platform_create_egl_surface(EGLDisplay dpy, EGLConfig config,
109 void *native_window,
110 const EGLint *attrib_list)
111 {
112 static PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC
113 create_platform_window = NULL;
114
115 if (!create_platform_window) {
116 create_platform_window = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)
117 weston_platform_get_egl_proc_address(
118 "eglCreatePlatformWindowSurfaceEXT");
119 }
120
121 if (create_platform_window)
122 return create_platform_window(dpy, config,
123 native_window,
124 attrib_list);
125
126 return eglCreateWindowSurface(dpy, config,
127 (EGLNativeWindowType) native_window,
128 attrib_list);
129 }
130
131 static inline EGLBoolean
weston_platform_destroy_egl_surface(EGLDisplay display,EGLSurface surface)132 weston_platform_destroy_egl_surface(EGLDisplay display,
133 EGLSurface surface)
134 {
135 return eglDestroySurface(display, surface);
136 }
137
138 #else /* ENABLE_EGL */
139
140 static inline void *
141 weston_platform_get_egl_display(int platform, void *native_display,
142 const int *attrib_list)
143 {
144 return NULL;
145 }
146
147 static inline void *
148 weston_platform_create_egl_surface(void *dpy, void *config,
149 void *native_window,
150 const int *attrib_list)
151 {
152 return NULL;
153 }
154
155 static inline unsigned int
156 weston_platform_destroy_egl_surface(void *display,
157 void *surface)
158 {
159 return 1;
160 }
161 #endif /* ENABLE_EGL */
162
163 #ifdef __cplusplus
164 }
165 #endif
166
167 #endif /* WESTON_PLATFORM_H */
168