Add Chromium-only Blender WebEngine parity work

This commit is contained in:
mes123456
2026-08-12 04:47:48 -04:00
commit 9fd26010f6
18225 changed files with 11622124 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
# SPDX-FileCopyrightText: 2022 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
set(INC
extern
# For internal includes.
intern
)
set(INC_SYS
${wayland-client_INCLUDE_DIRS}
${wayland-cursor_INCLUDE_DIRS}
)
set(SRC
intern/wayland_dynload_client.c
intern/wayland_dynload_cursor.c
intern/wayland_dynload_utils.c
extern/wayland_dynload_API.h
extern/wayland_dynload_client.h
extern/wayland_dynload_cursor.h
intern/wayland_dynload_utils.h
)
if(WITH_OPENGL_BACKEND)
list(APPEND INC_SYS
${wayland-egl_INCLUDE_DIRS}
)
list(APPEND SRC
intern/wayland_dynload_egl.c
extern/wayland_dynload_egl.h
)
add_definitions(-DWITH_OPENGL_BACKEND)
endif()
set(LIB
)
blender_add_lib(bf_intern_wayland_dynload "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

View File

@@ -0,0 +1,30 @@
/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup intern_wayland_dynload
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
bool wayland_dynload_client_init(bool verbose);
void wayland_dynload_client_exit(void);
bool wayland_dynload_cursor_init(bool verbose);
void wayland_dynload_cursor_exit(void);
#ifdef WITH_OPENGL_BACKEND
bool wayland_dynload_egl_init(bool verbose);
void wayland_dynload_egl_exit(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,175 @@
/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup intern_wayland_dynload
*
* Wrapper functions for `<wayland-client.h>`.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WAYLAND_DYNLOAD_FN
WAYLAND_DYNLOAD_FN(wl_display_connect)
WAYLAND_DYNLOAD_FN(wl_display_disconnect)
WAYLAND_DYNLOAD_FN(wl_display_dispatch)
WAYLAND_DYNLOAD_FN(wl_display_dispatch_pending)
WAYLAND_DYNLOAD_FN(wl_display_dispatch_queue)
WAYLAND_DYNLOAD_FN(wl_display_create_queue)
WAYLAND_DYNLOAD_FN(wl_display_get_fd)
WAYLAND_DYNLOAD_FN(wl_display_get_protocol_error)
WAYLAND_DYNLOAD_FN(wl_display_prepare_read)
WAYLAND_DYNLOAD_FN(wl_display_read_events)
WAYLAND_DYNLOAD_FN(wl_display_cancel_read)
WAYLAND_DYNLOAD_FN(wl_display_roundtrip)
WAYLAND_DYNLOAD_FN(wl_display_flush)
WAYLAND_DYNLOAD_FN(wl_display_get_error)
WAYLAND_DYNLOAD_FN(wl_event_queue_destroy)
WAYLAND_DYNLOAD_FN(wl_log_set_handler_client)
WAYLAND_DYNLOAD_FN(wl_proxy_add_listener)
WAYLAND_DYNLOAD_FN(wl_proxy_destroy)
WAYLAND_DYNLOAD_FN(wl_proxy_marshal_flags)
WAYLAND_DYNLOAD_FN(wl_proxy_marshal_array_flags)
WAYLAND_DYNLOAD_FN(wl_proxy_set_queue)
WAYLAND_DYNLOAD_FN(wl_proxy_set_user_data)
WAYLAND_DYNLOAD_FN(wl_proxy_get_user_data)
WAYLAND_DYNLOAD_FN(wl_proxy_get_version)
WAYLAND_DYNLOAD_FN(wl_proxy_get_tag)
WAYLAND_DYNLOAD_FN(wl_proxy_set_tag)
#elif defined(WAYLAND_DYNLOAD_IFACE)
WAYLAND_DYNLOAD_IFACE(wl_buffer_interface)
WAYLAND_DYNLOAD_IFACE(wl_compositor_interface)
WAYLAND_DYNLOAD_IFACE(wl_data_device_interface)
WAYLAND_DYNLOAD_IFACE(wl_data_device_manager_interface)
WAYLAND_DYNLOAD_IFACE(wl_data_source_interface)
WAYLAND_DYNLOAD_IFACE(wl_keyboard_interface)
WAYLAND_DYNLOAD_IFACE(wl_output_interface)
WAYLAND_DYNLOAD_IFACE(wl_pointer_interface)
WAYLAND_DYNLOAD_IFACE(wl_region_interface)
WAYLAND_DYNLOAD_IFACE(wl_registry_interface)
WAYLAND_DYNLOAD_IFACE(wl_seat_interface)
WAYLAND_DYNLOAD_IFACE(wl_shm_interface)
WAYLAND_DYNLOAD_IFACE(wl_shm_pool_interface)
WAYLAND_DYNLOAD_IFACE(wl_surface_interface)
WAYLAND_DYNLOAD_IFACE(wl_touch_interface)
#else
/* Header guard. */
# if !defined(__WAYLAND_DYNLOAD_CLIENT_H__) && !defined(WAYLAND_DYNLOAD_VALIDATE)
# define __WAYLAND_DYNLOAD_CLIENT_H__
# ifndef WAYLAND_DYNLOAD_VALIDATE
# include <wayland-client-core.h>
extern struct WaylandDynload_Client wayland_dynload_client;
# endif
/* Support validating declarations against the header. */
# ifndef WAYLAND_DYNLOAD_VALIDATE
# define WL_DYN_FN(a) (*a)
# else
# define WL_DYN_FN(a) (a)
# endif
# ifndef WAYLAND_DYNLOAD_VALIDATE
struct WaylandDynload_Client {
# endif
struct wl_display *WL_DYN_FN(wl_display_connect)(const char *name);
void WL_DYN_FN(wl_display_disconnect)(struct wl_display *display);
int WL_DYN_FN(wl_display_dispatch)(struct wl_display *display);
int WL_DYN_FN(wl_display_roundtrip)(struct wl_display *display);
int WL_DYN_FN(wl_display_dispatch_pending)(struct wl_display *display);
int WL_DYN_FN(wl_display_dispatch_queue)(struct wl_display *display,
struct wl_event_queue *queue);
struct wl_event_queue *WL_DYN_FN(wl_display_create_queue)(struct wl_display *display);
int WL_DYN_FN(wl_display_get_fd)(struct wl_display *display);
uint32_t WL_DYN_FN(wl_display_get_protocol_error)(struct wl_display *display,
const struct wl_interface **interface,
uint32_t *id);
int WL_DYN_FN(wl_display_prepare_read)(struct wl_display *display);
int WL_DYN_FN(wl_display_read_events)(struct wl_display *display);
void WL_DYN_FN(wl_display_cancel_read)(struct wl_display *display);
int WL_DYN_FN(wl_display_flush)(struct wl_display *display);
int WL_DYN_FN(wl_display_get_error)(struct wl_display *display);
void WL_DYN_FN(wl_event_queue_destroy)(struct wl_event_queue *queue);
void WL_DYN_FN(wl_log_set_handler_client)(wl_log_func_t);
int WL_DYN_FN(wl_proxy_add_listener)(struct wl_proxy *proxy,
void (**implementation)(void),
void *data);
void WL_DYN_FN(wl_proxy_destroy)(struct wl_proxy *proxy);
struct wl_proxy *WL_DYN_FN(wl_proxy_marshal_flags)(struct wl_proxy *proxy,
uint32_t opcode,
const struct wl_interface *interface,
uint32_t version,
uint32_t flags,
...);
struct wl_proxy *WL_DYN_FN(wl_proxy_marshal_array_flags)(struct wl_proxy *proxy,
uint32_t opcode,
const struct wl_interface *interface,
uint32_t version,
uint32_t flags,
union wl_argument *args);
void WL_DYN_FN(wl_proxy_set_queue)(struct wl_proxy *proxy, struct wl_event_queue *queue);
void WL_DYN_FN(wl_proxy_set_user_data)(struct wl_proxy *proxy, void *user_data);
void *WL_DYN_FN(wl_proxy_get_user_data)(struct wl_proxy *proxy);
uint32_t WL_DYN_FN(wl_proxy_get_version)(struct wl_proxy *proxy);
const char *const *WL_DYN_FN(wl_proxy_get_tag)(struct wl_proxy *proxy);
void WL_DYN_FN(wl_proxy_set_tag)(struct wl_proxy *proxy, const char *const *tag);
# ifndef WAYLAND_DYNLOAD_VALIDATE
};
# endif
# undef WL_DYN_FN
# ifndef WAYLAND_DYNLOAD_VALIDATE
# define wl_display_connect(...) (*wayland_dynload_client.wl_display_connect)(__VA_ARGS__)
# define wl_display_disconnect(...) \
(*wayland_dynload_client.wl_display_disconnect)(__VA_ARGS__)
# define wl_display_dispatch(...) (*wayland_dynload_client.wl_display_dispatch)(__VA_ARGS__)
# define wl_display_dispatch_pending(...) \
(*wayland_dynload_client.wl_display_dispatch_pending)(__VA_ARGS__)
# define wl_display_dispatch_queue(...) \
(*wayland_dynload_client.wl_display_dispatch_queue)(__VA_ARGS__)
# define wl_display_create_queue(...) \
(*wayland_dynload_client.wl_display_create_queue)(__VA_ARGS__)
# define wl_display_get_fd(...) (*wayland_dynload_client.wl_display_get_fd)(__VA_ARGS__)
# define wl_display_get_protocol_error(...) \
(*wayland_dynload_client.wl_display_get_protocol_error)(__VA_ARGS__)
# define wl_display_prepare_read(...) \
(*wayland_dynload_client.wl_display_prepare_read)(__VA_ARGS__)
# define wl_display_read_events(...) \
(*wayland_dynload_client.wl_display_read_events)(__VA_ARGS__)
# define wl_display_cancel_read(...) \
(*wayland_dynload_client.wl_display_cancel_read)(__VA_ARGS__)
# define wl_display_roundtrip(...) (*wayland_dynload_client.wl_display_roundtrip)(__VA_ARGS__)
# define wl_display_flush(...) (*wayland_dynload_client.wl_display_flush)(__VA_ARGS__)
# define wl_display_get_error(...) (*wayland_dynload_client.wl_display_get_error)(__VA_ARGS__)
# define wl_event_queue_destroy(...) \
(*wayland_dynload_client.wl_event_queue_destroy)(__VA_ARGS__)
# define wl_log_set_handler_client(...) \
(*wayland_dynload_client.wl_log_set_handler_client)(__VA_ARGS__)
# define wl_proxy_add_listener(...) \
(*wayland_dynload_client.wl_proxy_add_listener)(__VA_ARGS__)
# define wl_proxy_destroy(...) (*wayland_dynload_client.wl_proxy_destroy)(__VA_ARGS__)
# define wl_proxy_marshal_flags(...) \
(*wayland_dynload_client.wl_proxy_marshal_flags)(__VA_ARGS__)
# define wl_proxy_marshal_array_flags(...) \
(*wayland_dynload_client.wl_proxy_marshal_array_flags)(__VA_ARGS__)
# define wl_proxy_set_queue(...) (*wayland_dynload_client.wl_proxy_set_queue)(__VA_ARGS__)
# define wl_proxy_set_user_data(...) \
(*wayland_dynload_client.wl_proxy_set_user_data)(__VA_ARGS__)
# define wl_proxy_get_user_data(...) \
(*wayland_dynload_client.wl_proxy_get_user_data)(__VA_ARGS__)
# define wl_proxy_get_version(...) (*wayland_dynload_client.wl_proxy_get_version)(__VA_ARGS__)
# define wl_proxy_get_tag(...) (*wayland_dynload_client.wl_proxy_get_tag)(__VA_ARGS__)
# define wl_proxy_set_tag(...) (*wayland_dynload_client.wl_proxy_set_tag)(__VA_ARGS__)
# endif /* !WAYLAND_DYNLOAD_VALIDATE */
# endif /* !defined(__WAYLAND_DYNLOAD_CLIENT_H__) && !defined(WAYLAND_DYNLOAD_VALIDATE) */
#endif /* !defined(WAYLAND_DYNLOAD_FN) && !defined(WAYLAND_DYNLOAD_IFACE) */
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,78 @@
/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup intern_wayland_dynload
*
* Wrapper functions for `<wayland-cursor.h>`.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WAYLAND_DYNLOAD_FN
WAYLAND_DYNLOAD_FN(wl_cursor_theme_load)
WAYLAND_DYNLOAD_FN(wl_cursor_theme_destroy)
WAYLAND_DYNLOAD_FN(wl_cursor_theme_get_cursor)
WAYLAND_DYNLOAD_FN(wl_cursor_image_get_buffer)
WAYLAND_DYNLOAD_FN(wl_cursor_frame)
WAYLAND_DYNLOAD_FN(wl_cursor_frame_and_duration)
#elif defined(WAYLAND_DYNLOAD_IFACE)
/* No interfaces. */
#else
/* Header guard. */
# if !defined(__WAYLAND_DYNLOAD_CURSOR_H__) && !defined(WAYLAND_DYNLOAD_VALIDATE)
# define __WAYLAND_DYNLOAD_CURSOR_H__
# include <wayland-cursor.h>
extern struct WaylandDynload_Cursor wayland_dynload_cursor;
/* Support validating declarations against the header. */
# ifndef WAYLAND_DYNLOAD_VALIDATE
# define WL_DYN_FN(a) (*a)
# else
# define WL_DYN_FN(a) (a)
# endif
# ifndef WAYLAND_DYNLOAD_VALIDATE
struct WaylandDynload_Cursor {
# endif
struct wl_cursor_theme *WL_DYN_FN(wl_cursor_theme_load)(const char *name,
int size,
struct wl_shm *shm);
void WL_DYN_FN(wl_cursor_theme_destroy)(struct wl_cursor_theme *theme);
struct wl_cursor *WL_DYN_FN(wl_cursor_theme_get_cursor)(struct wl_cursor_theme *theme,
const char *name);
struct wl_buffer *WL_DYN_FN(wl_cursor_image_get_buffer)(struct wl_cursor_image *image);
int WL_DYN_FN(wl_cursor_frame)(struct wl_cursor *cursor, uint32_t time);
int WL_DYN_FN(wl_cursor_frame_and_duration)(struct wl_cursor *cursor,
uint32_t time,
uint32_t *duration);
# ifndef WAYLAND_DYNLOAD_VALIDATE
};
# endif
# undef WL_DYN_FN
# ifndef WAYLAND_DYNLOAD_VALIDATE
# define wl_cursor_theme_load(...) (*wayland_dynload_cursor.wl_cursor_theme_load)(__VA_ARGS__)
# define wl_cursor_theme_destroy(...) \
(*wayland_dynload_cursor.wl_cursor_theme_destroy)(__VA_ARGS__)
# define wl_cursor_theme_get_cursor(...) \
(*wayland_dynload_cursor.wl_cursor_theme_get_cursor)(__VA_ARGS__)
# define wl_cursor_image_get_buffer(...) \
(*wayland_dynload_cursor.wl_cursor_image_get_buffer)(__VA_ARGS__)
# define wl_cursor_frame(...) (*wayland_dynload_cursor.wl_cursor_frame)(__VA_ARGS__)
# define wl_cursor_frame_and_duration(...) \
(*wayland_dynload_cursor.wl_cursor_frame_and_duration)(__VA_ARGS__)
# endif /* !WAYLAND_DYNLOAD_VALIDATE */
# endif /* !__WAYLAND_DYNLOAD_CLIENT_H__ */
#endif /* !defined(WAYLAND_DYNLOAD_FN) && !defined(WAYLAND_DYNLOAD_IFACE) */
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,70 @@
/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup intern_wayland_dynload
*
* Wrapper functions for `<wayland-egl.h>`.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WAYLAND_DYNLOAD_FN
WAYLAND_DYNLOAD_FN(wl_egl_window_create)
WAYLAND_DYNLOAD_FN(wl_egl_window_destroy)
WAYLAND_DYNLOAD_FN(wl_egl_window_resize)
WAYLAND_DYNLOAD_FN(wl_egl_window_get_attached_size)
#elif defined(WAYLAND_DYNLOAD_IFACE)
/* No interfaces. */
#else
/* Header guard. */
# if !defined(__WAYLAND_DYNLOAD_EGL_H__) && !defined(WAYLAND_DYNLOAD_VALIDATE)
# define __WAYLAND_DYNLOAD_EGL_H__
# include <wayland-egl-core.h>
extern struct WaylandDynload_EGL wayland_dynload_egl;
/* Support validating declarations against the header. */
# ifndef WAYLAND_DYNLOAD_VALIDATE
# define WL_DYN_FN(a) (*a)
# else
# define WL_DYN_FN(a) (a)
# endif
# ifndef WAYLAND_DYNLOAD_VALIDATE
struct WaylandDynload_EGL {
# endif
struct wl_egl_window *WL_DYN_FN(wl_egl_window_create)(struct wl_surface *surface,
int width,
int height);
void WL_DYN_FN(wl_egl_window_destroy)(struct wl_egl_window *egl_window);
void WL_DYN_FN(wl_egl_window_resize)(
struct wl_egl_window *egl_window, int width, int height, int dx, int dy);
void WL_DYN_FN(wl_egl_window_get_attached_size)(struct wl_egl_window *egl_window,
int *width,
int *height);
# ifndef WAYLAND_DYNLOAD_VALIDATE
};
# endif
# undef WL_DYN_FN
# ifndef WAYLAND_DYNLOAD_VALIDATE
# define wl_egl_window_create(...) (*wayland_dynload_egl.wl_egl_window_create)(__VA_ARGS__)
# define wl_egl_window_destroy(...) (*wayland_dynload_egl.wl_egl_window_destroy)(__VA_ARGS__)
# define wl_egl_window_resize(...) (*wayland_dynload_egl.wl_egl_window_resize)(__VA_ARGS__)
# define wl_egl_window_get_attached_size(...) \
(*wayland_dynload_egl.wl_egl_window_get_attached_size)(__VA_ARGS__)
# endif /* !WAYLAND_DYNLOAD_VALIDATE */
# endif /* !defined(WAYLAND_DYNLOAD_FN) && !defined(WAYLAND_DYNLOAD_IFACE) */
#endif /* !defined(__WAYLAND_DYNLOAD_EGL_H__) && !defined(WAYLAND_DYNLOAD_VALIDATE) */
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,89 @@
/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup intern_wayland_dynload
*
* Wrapper functions for `<wayland-client.h>`.
*/
#include <stdlib.h> /* `atexit`. */
#include <string.h>
#include "wayland_dynload_API.h"
#include "wayland_dynload_utils.h"
#include "wayland_dynload_client.h" /* Own include. */
/* Public handle. */
struct WaylandDynload_Client wayland_dynload_client = {NULL};
static DynamicLibrary lib = NULL;
#define WAYLAND_DYNLOAD_IFACE(symbol) \
extern struct wl_interface symbol; \
struct wl_interface symbol;
#include "wayland_dynload_client.h"
#undef WAYLAND_DYNLOAD_IFACE
bool wayland_dynload_client_init(const bool verbose)
{
/* NOTE: returning false must call exit to prevent leaking `lib`
* once it has been opened. */
/* Library paths. */
const char *paths[] = {
"libwayland-client.so.0",
"libwayland-client.so",
};
const int paths_num = sizeof(paths) / sizeof(*paths);
int path_found;
if (!(lib = dynamic_library_open_array_with_error(paths, paths_num, verbose, &path_found))) {
return false;
}
if (atexit(wayland_dynload_client_exit)) {
wayland_dynload_client_exit();
return false;
}
#define WAYLAND_DYNLOAD_IFACE(symbol) \
{ \
const void *symbol_val; \
if (!(symbol_val = dynamic_library_find_with_error( \
lib, #symbol, paths[path_found], verbose))) { \
wayland_dynload_client_exit(); \
return false; \
} \
memcpy(&symbol, symbol_val, sizeof(symbol)); \
}
#include "wayland_dynload_client.h"
#undef WAYLAND_DYNLOAD_IFACE
#define WAYLAND_DYNLOAD_FN(symbol) \
if (!(wayland_dynload_client.symbol = dynamic_library_find_with_error( \
lib, #symbol, paths[path_found], verbose))) \
{ \
wayland_dynload_client_exit(); \
return false; \
}
#include "wayland_dynload_client.h"
#undef WAYLAND_DYNLOAD_FN
return true;
}
void wayland_dynload_client_exit(void)
{
if (lib != NULL) {
dynamic_library_close(lib); /* Ignore errors. */
lib = NULL;
}
}
/* Validate local signatures against the original header. */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wredundant-decls"
#define WAYLAND_DYNLOAD_VALIDATE
#include "wayland_dynload_client.h"
#pragma GCC diagnostic pop

View File

@@ -0,0 +1,69 @@
/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup intern_wayland_dynload
*
* Wrapper functions for `<wayland-cursor.h>`.
*/
#include <stdlib.h> /* `atexit`. */
#include <string.h>
#include "wayland_dynload_API.h"
#include "wayland_dynload_utils.h"
#include "wayland_dynload_cursor.h" /* Own include. */
struct WaylandDynload_Cursor wayland_dynload_cursor = {NULL};
static DynamicLibrary lib = NULL;
bool wayland_dynload_cursor_init(const bool verbose)
{
/* NOTE: returning false must call exit to prevent leaking `lib`
* once it has been opened. */
/* Library paths. */
const char *paths[] = {
"libwayland-cursor.so.0",
"libwayland-cursor.so",
};
const int paths_num = sizeof(paths) / sizeof(*paths);
int path_index;
if (!(lib = dynamic_library_open_array_with_error(paths, paths_num, verbose, &path_index))) {
return false;
}
if (atexit(wayland_dynload_cursor_exit)) {
wayland_dynload_cursor_exit();
return false;
}
#define WAYLAND_DYNLOAD_FN(symbol) \
if (!(wayland_dynload_cursor.symbol = dynamic_library_find_with_error( \
lib, #symbol, paths[path_index], verbose))) \
{ \
wayland_dynload_cursor_exit(); \
return false; \
}
#include "wayland_dynload_cursor.h"
#undef WAYLAND_DYNLOAD_FN
return true;
}
void wayland_dynload_cursor_exit(void)
{
if (lib != NULL) {
dynamic_library_close(lib); /* Ignore errors. */
lib = NULL;
}
}
/* Validate local signatures against the original header. */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wredundant-decls"
#define WAYLAND_DYNLOAD_VALIDATE
#include "wayland_dynload_cursor.h"
#pragma GCC diagnostic pop

View File

@@ -0,0 +1,69 @@
/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup intern_wayland_dynload
*
* Wrapper functions for `<wayland-egl.h>`.
*/
#include <stdlib.h> /* `atexit`. */
#include "wayland_dynload_API.h"
#include "wayland_dynload_utils.h"
#include "wayland_dynload_egl.h" /* Own include. */
/* Public handle. */
struct WaylandDynload_EGL wayland_dynload_egl = {NULL};
static DynamicLibrary lib = NULL;
bool wayland_dynload_egl_init(const bool verbose)
{
/* NOTE: returning false must call exit to prevent leaking `lib`
* once it has been opened. */
/* Library paths. */
const char *paths[] = {
"libwayland-egl.so.1",
"libwayland-egl.so",
};
const int paths_num = sizeof(paths) / sizeof(*paths);
int path_found = 0;
if (!(lib = dynamic_library_open_array_with_error(paths, paths_num, verbose, &path_found))) {
return false;
}
if (atexit(wayland_dynload_egl_exit)) {
wayland_dynload_egl_exit();
return false;
}
#define WAYLAND_DYNLOAD_FN(symbol) \
if (!(wayland_dynload_egl.symbol = dynamic_library_find_with_error( \
lib, #symbol, paths[path_found], verbose))) \
{ \
wayland_dynload_egl_exit(); \
return false; \
}
#include "wayland_dynload_egl.h"
#undef WAYLAND_DYNLOAD_FN
return true;
}
void wayland_dynload_egl_exit(void)
{
if (lib != NULL) {
dynamic_library_close(lib); /* Ignore errors. */
lib = NULL;
}
}
/* Validate local signatures against the original header. */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wredundant-decls"
#define WAYLAND_DYNLOAD_VALIDATE
#include "wayland_dynload_egl.h"
#pragma GCC diagnostic pop

View File

@@ -0,0 +1,47 @@
/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup intern_wayland_dynload
*/
#include <stdio.h>
#include "wayland_dynload_utils.h"
DynamicLibrary dynamic_library_open_array_with_error(const char **paths,
const int paths_num,
const bool verbose,
int *r_path_index)
{
DynamicLibrary lib = NULL;
for (int a = 0; a < paths_num; a++) {
lib = dynamic_library_open(paths[a]);
if (lib) {
*r_path_index = a;
break;
}
}
if (lib == NULL) {
/* Use the last path as it's likely to be least specific. */
if (verbose) {
fprintf(stderr, "Unable to find '%s'\n", paths[paths_num - 1]);
}
}
return lib;
}
void *dynamic_library_find_with_error(DynamicLibrary lib,
const char *symbol,
const char *path_lib,
const bool verbose)
{
void *symbol_var = dynamic_library_find(lib, symbol);
if (symbol_var == NULL) {
if (verbose) {
fprintf(stderr, "Unable to find '%s' in '%s'.\n", symbol, path_lib);
}
}
return symbol_var;
}

View File

@@ -0,0 +1,32 @@
/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup intern_wayland_dynload
*
* Utility defines.
*/
#pragma once
#include <dlfcn.h> /* Dynamic loading. */
#include <stdbool.h>
typedef void *DynamicLibrary;
#define dynamic_library_open(path) dlopen(path, RTLD_NOW)
#define dynamic_library_close(lib) dlclose(lib)
#define dynamic_library_find(lib, symbol) dlsym(lib, symbol)
/** Loads a library from an array, printing an error when the symbol isn't found. */
DynamicLibrary dynamic_library_open_array_with_error(const char **paths,
int paths_num,
bool verbose,
int *r_path_index);
/** Find a symbol, printing an error when the symbol isn't found. */
void *dynamic_library_find_with_error(DynamicLibrary lib,
const char *symbol,
const char *path_lib,
bool verbose);