1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org> |
4 | |
5 | This software is provided 'as-is', without any express or implied |
6 | warranty. In no event will the authors be held liable for any damages |
7 | arising from the use of this software. |
8 | |
9 | Permission is granted to anyone to use this software for any purpose, |
10 | including commercial applications, and to alter it and redistribute it |
11 | freely, subject to the following restrictions: |
12 | |
13 | 1. The origin of this software must not be misrepresented; you must not |
14 | claim that you wrote the original software. If you use this software |
15 | in a product, an acknowledgment in the product documentation would be |
16 | appreciated but is not required. |
17 | 2. Altered source versions must be plainly marked as such, and must not be |
18 | misrepresented as being the original software. |
19 | 3. This notice may not be removed or altered from any source distribution. |
20 | */ |
21 | #include "../../SDL_internal.h" |
22 | |
23 | #if SDL_VIDEO_DRIVER_WAYLAND |
24 | |
25 | #define DEBUG_DYNAMIC_WAYLAND 0 |
26 | |
27 | #include "SDL_waylanddyn.h" |
28 | |
29 | |
30 | #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC |
31 | |
32 | #include "SDL_name.h" |
33 | #include "SDL_loadso.h" |
34 | |
35 | typedef struct |
36 | { |
37 | void *lib; |
38 | const char *libname; |
39 | } waylanddynlib; |
40 | |
41 | #ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL |
42 | #define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL NULL |
43 | #endif |
44 | #ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR |
45 | #define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR NULL |
46 | #endif |
47 | #ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON |
48 | #define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON NULL |
49 | #endif |
50 | |
51 | static waylanddynlib waylandlibs[] = { |
52 | {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC}, |
53 | {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL}, |
54 | {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR}, |
55 | {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON} |
56 | }; |
57 | |
58 | static void * |
59 | WAYLAND_GetSym(const char *fnname, int *pHasModule) |
60 | { |
61 | int i; |
62 | void *fn = NULL; |
63 | for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) { |
64 | if (waylandlibs[i].lib != NULL) { |
65 | fn = SDL_LoadFunction(waylandlibs[i].lib, fnname); |
66 | if (fn != NULL) |
67 | break; |
68 | } |
69 | } |
70 | |
71 | #if DEBUG_DYNAMIC_WAYLAND |
72 | if (fn != NULL) |
73 | SDL_Log("WAYLAND: Found '%s' in %s (%p)\n" , fnname, waylandlibs[i].libname, fn); |
74 | else |
75 | SDL_Log("WAYLAND: Symbol '%s' NOT FOUND!\n" , fnname); |
76 | #endif |
77 | |
78 | if (fn == NULL) |
79 | *pHasModule = 0; /* kill this module. */ |
80 | |
81 | return fn; |
82 | } |
83 | |
84 | #endif /* SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */ |
85 | |
86 | /* Define all the function pointers and wrappers... */ |
87 | #define SDL_WAYLAND_MODULE(modname) int SDL_WAYLAND_HAVE_##modname = 0; |
88 | #define SDL_WAYLAND_SYM(rc,fn,params) SDL_DYNWAYLANDFN_##fn WAYLAND_##fn = NULL; |
89 | #define SDL_WAYLAND_INTERFACE(iface) const struct wl_interface *WAYLAND_##iface = NULL; |
90 | #include "SDL_waylandsym.h" |
91 | |
92 | static int wayland_load_refcount = 0; |
93 | |
94 | void |
95 | SDL_WAYLAND_UnloadSymbols(void) |
96 | { |
97 | /* Don't actually unload if more than one module is using the libs... */ |
98 | if (wayland_load_refcount > 0) { |
99 | if (--wayland_load_refcount == 0) { |
100 | #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC |
101 | int i; |
102 | #endif |
103 | |
104 | /* set all the function pointers to NULL. */ |
105 | #define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 0; |
106 | #define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = NULL; |
107 | #define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = NULL; |
108 | #include "SDL_waylandsym.h" |
109 | |
110 | |
111 | #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC |
112 | for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) { |
113 | if (waylandlibs[i].lib != NULL) { |
114 | SDL_UnloadObject(waylandlibs[i].lib); |
115 | waylandlibs[i].lib = NULL; |
116 | } |
117 | } |
118 | #endif |
119 | } |
120 | } |
121 | } |
122 | |
123 | /* returns non-zero if all needed symbols were loaded. */ |
124 | int |
125 | SDL_WAYLAND_LoadSymbols(void) |
126 | { |
127 | int rc = 1; /* always succeed if not using Dynamic WAYLAND stuff. */ |
128 | |
129 | /* deal with multiple modules (dga, wayland, etc) needing these symbols... */ |
130 | if (wayland_load_refcount++ == 0) { |
131 | #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC |
132 | int i; |
133 | int *thismod = NULL; |
134 | for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) { |
135 | if (waylandlibs[i].libname != NULL) { |
136 | waylandlibs[i].lib = SDL_LoadObject(waylandlibs[i].libname); |
137 | } |
138 | } |
139 | |
140 | #define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 1; /* default yes */ |
141 | #include "SDL_waylandsym.h" |
142 | |
143 | #define SDL_WAYLAND_MODULE(modname) thismod = &SDL_WAYLAND_HAVE_##modname; |
144 | #define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = (SDL_DYNWAYLANDFN_##fn) WAYLAND_GetSym(#fn,thismod); |
145 | #define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = (struct wl_interface *) WAYLAND_GetSym(#iface,thismod); |
146 | #include "SDL_waylandsym.h" |
147 | |
148 | if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT) { |
149 | /* all required symbols loaded. */ |
150 | SDL_ClearError(); |
151 | } else { |
152 | /* in case something got loaded... */ |
153 | SDL_WAYLAND_UnloadSymbols(); |
154 | rc = 0; |
155 | } |
156 | |
157 | #else /* no dynamic WAYLAND */ |
158 | |
159 | #define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 1; /* default yes */ |
160 | #define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = fn; |
161 | #define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = &iface; |
162 | #include "SDL_waylandsym.h" |
163 | |
164 | #endif |
165 | } |
166 | |
167 | return rc; |
168 | } |
169 | |
170 | #endif /* SDL_VIDEO_DRIVER_WAYLAND */ |
171 | |
172 | /* vi: set ts=4 sw=4 expandtab: */ |
173 | |