[Linux] Make SO wrapper usage optional.

This commit is contained in:
bruvzg 2023-02-15 14:13:56 +02:00
parent 953383328a
commit dd068794c3
No known key found for this signature in database
GPG Key ID: 7960FCF39844EC38
21 changed files with 259 additions and 32 deletions

View File

@ -3,6 +3,7 @@
Import("env")
if "alsa" in env and env["alsa"]:
if env["use_sowrap"]:
env.add_source_files(env.drivers_sources, "asound-so_wrap.c")
env.add_source_files(env.drivers_sources, "*.cpp")

View File

@ -37,7 +37,7 @@
#include <errno.h>
#ifdef PULSEAUDIO_ENABLED
#if defined(PULSEAUDIO_ENABLED) && defined(SOWRAP_ENABLED)
extern "C" {
extern int initialize_pulse(int verbose);
}
@ -153,6 +153,7 @@ Error AudioDriverALSA::init_output_device() {
}
Error AudioDriverALSA::init() {
#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
@ -167,7 +168,7 @@ Error AudioDriverALSA::init() {
if (initialize_asound(dylibloader_verbose)) {
return ERR_CANT_OPEN;
}
#endif
active.clear();
exit_thread.clear();

View File

@ -38,7 +38,11 @@
#include "core/templates/safe_refcount.h"
#include "servers/audio_server.h"
#ifdef SOWRAP_ENABLED
#include "asound-so_wrap.h"
#else
#include <alsa/asoundlib.h>
#endif
class AudioDriverALSA : public AudioDriver {
Thread thread;

View File

@ -39,7 +39,12 @@
#include "core/templates/safe_refcount.h"
#include "core/templates/vector.h"
#ifdef SOWRAP_ENABLED
#include "../alsa/asound-so_wrap.h"
#else
#include <alsa/asoundlib.h>
#endif
#include <stdio.h>
class MIDIDriverALSAMidi : public MIDIDriver {

View File

@ -3,6 +3,7 @@
Import("env")
if "pulseaudio" in env and env["pulseaudio"]:
if env["use_sowrap"]:
env.add_source_files(env.drivers_sources, "pulse-so_wrap.c")
env.add_source_files(env.drivers_sources, "*.cpp")

View File

@ -37,7 +37,11 @@
#include "core/version.h"
#ifdef ALSAMIDI_ENABLED
#ifdef SOWRAP_ENABLED
#include "drivers/alsa/asound-so_wrap.h"
#else
#include <alsa/asoundlib.h>
#endif
#endif
void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) {
@ -272,6 +276,7 @@ Error AudioDriverPulseAudio::init_output_device() {
}
Error AudioDriverPulseAudio::init() {
#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
@ -284,7 +289,7 @@ Error AudioDriverPulseAudio::init() {
if (initialize_pulse(dylibloader_verbose)) {
return ERR_CANT_OPEN;
}
#endif
active.clear();
exit_thread.clear();

View File

@ -38,7 +38,11 @@
#include "core/templates/safe_refcount.h"
#include "servers/audio_server.h"
#ifdef SOWRAP_ENABLED
#include "pulse-so_wrap.h"
#else
#include <pulse/pulseaudio.h>
#endif
class AudioDriverPulseAudio : public AudioDriver {
Thread thread;

View File

@ -11,22 +11,29 @@ common_linuxbsd = [
"joypad_linux.cpp",
"freedesktop_portal_desktop.cpp",
"freedesktop_screensaver.cpp",
"xkbcommon-so_wrap.c",
]
if env["use_sowrap"]:
common_linuxbsd.append("xkbcommon-so_wrap.c")
if env["x11"]:
common_linuxbsd += SConscript("x11/SCsub")
if env["speechd"]:
common_linuxbsd.append(["speechd-so_wrap.c", "tts_linux.cpp"])
common_linuxbsd.append("tts_linux.cpp")
if env["use_sowrap"]:
common_linuxbsd.append("speechd-so_wrap.c")
if env["fontconfig"]:
if env["use_sowrap"]:
common_linuxbsd.append("fontconfig-so_wrap.c")
if env["udev"]:
if env["use_sowrap"]:
common_linuxbsd.append("libudev-so_wrap.c")
if env["dbus"]:
if env["use_sowrap"]:
common_linuxbsd.append("dbus-so_wrap.c")
prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_linuxbsd)

View File

@ -43,6 +43,7 @@ def get_opts():
BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN)", False),
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN)", False),
BoolVariable("use_msan", "Use LLVM compiler memory sanitizer (MSAN)", False),
BoolVariable("use_sowrap", "Dynamically load system libraries", True),
BoolVariable("alsa", "Use ALSA", True),
BoolVariable("pulseaudio", "Use PulseAudio", True),
BoolVariable("dbus", "Use D-Bus to handle screensaver and portal desktop settings", True),
@ -184,6 +185,9 @@ def configure(env: "Environment"):
## Dependencies
if env["use_sowrap"]:
env.Append(CPPDEFINES=["SOWRAP_ENABLED"])
if env["touch"]:
env.Append(CPPDEFINES=["TOUCH_ENABLED"])
@ -271,25 +275,82 @@ def configure(env: "Environment"):
env.Append(LIBS=["embree3"])
## Flags
if env["fontconfig"]:
if not env["use_sowrap"]:
if os.system("pkg-config --exists fontconfig") == 0: # 0 means found
env.ParseConfig("pkg-config fontconfig --cflags --libs")
env.Append(CPPDEFINES=["FONTCONFIG_ENABLED"])
else:
print("Warning: fontconfig development libraries not found. Disabling the system fonts support.")
env["fontconfig"] = False
else:
env.Append(CPPDEFINES=["FONTCONFIG_ENABLED"])
if env["alsa"]:
if not env["use_sowrap"]:
if os.system("pkg-config --exists alsa") == 0: # 0 means found
env.ParseConfig("pkg-config alsa --cflags --libs")
env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"])
else:
print("Warning: ALSA development libraries not found. Disabling the ALSA audio driver.")
env["alsa"] = False
else:
env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"])
if env["pulseaudio"]:
if not env["use_sowrap"]:
if os.system("pkg-config --exists libpulse") == 0: # 0 means found
env.ParseConfig("pkg-config libpulse --cflags --libs")
env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED", "_REENTRANT"])
else:
print("Warning: PulseAudio development libraries not found. Disabling the PulseAudio audio driver.")
env["pulseaudio"] = False
env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED", "_REENTRANT"])
if env["dbus"]:
if not env["use_sowrap"]:
if os.system("pkg-config --exists dbus-1") == 0: # 0 means found
env.ParseConfig("pkg-config dbus-1 --cflags --libs")
env.Append(CPPDEFINES=["DBUS_ENABLED"])
else:
print("Warning: D-Bus development libraries not found. Disabling screensaver prevention.")
env["dbus"] = False
else:
env.Append(CPPDEFINES=["DBUS_ENABLED"])
if env["speechd"]:
if not env["use_sowrap"]:
if os.system("pkg-config --exists speech-dispatcher") == 0: # 0 means found
env.ParseConfig("pkg-config speech-dispatcher --cflags --libs")
env.Append(CPPDEFINES=["SPEECHD_ENABLED"])
else:
print("Warning: speech-dispatcher development libraries not found. Disabling text to speech support.")
env["speechd"] = False
else:
env.Append(CPPDEFINES=["SPEECHD_ENABLED"])
if not env["use_sowrap"]:
if os.system("pkg-config --exists xkbcommon") == 0: # 0 means found
env.ParseConfig("pkg-config xkbcommon --cflags --libs")
env.Append(CPPDEFINES=["XKB_ENABLED"])
else:
print(
"Warning: libxkbcommon development libraries not found. Disabling dead key composition and key label support."
)
else:
env.Append(CPPDEFINES=["XKB_ENABLED"])
if platform.system() == "Linux":
env.Append(CPPDEFINES=["JOYDEV_ENABLED"])
if env["udev"]:
if not env["use_sowrap"]:
if os.system("pkg-config --exists libudev") == 0: # 0 means found
env.ParseConfig("pkg-config libudev --cflags --libs")
env.Append(CPPDEFINES=["UDEV_ENABLED"])
else:
print("Warning: libudev development libraries not found. Disabling controller hotplugging support.")
env["udev"] = False
else:
env.Append(CPPDEFINES=["UDEV_ENABLED"])
else:
env["udev"] = False # Linux specific
@ -298,7 +359,9 @@ def configure(env: "Environment"):
if not env["builtin_zlib"]:
env.ParseConfig("pkg-config zlib --cflags --libs")
env.Prepend(CPPPATH=["#platform/linuxbsd", "#thirdparty/linuxbsd_headers"])
env.Prepend(CPPPATH=["#platform/linuxbsd"])
if env["use_sowrap"]:
env.Prepend(CPPPATH=["#thirdparty/linuxbsd_headers"])
env.Append(
CPPDEFINES=[
@ -309,6 +372,35 @@ def configure(env: "Environment"):
)
if env["x11"]:
if not env["use_sowrap"]:
if os.system("pkg-config --exists x11"):
print("Error: X11 libraries not found. Aborting.")
sys.exit(255)
env.ParseConfig("pkg-config x11 --cflags --libs")
if os.system("pkg-config --exists xcursor"):
print("Error: Xcursor library not found. Aborting.")
sys.exit(255)
env.ParseConfig("pkg-config xcursor --cflags --libs")
if os.system("pkg-config --exists xinerama"):
print("Error: Xinerama library not found. Aborting.")
sys.exit(255)
env.ParseConfig("pkg-config xinerama --cflags --libs")
if os.system("pkg-config --exists xext"):
print("Error: Xext library not found. Aborting.")
sys.exit(255)
env.ParseConfig("pkg-config xext --cflags --libs")
if os.system("pkg-config --exists xrandr"):
print("Error: XrandR library not found. Aborting.")
sys.exit(255)
env.ParseConfig("pkg-config xrandr --cflags --libs")
if os.system("pkg-config --exists xrender"):
print("Error: XRender library not found. Aborting.")
sys.exit(255)
env.ParseConfig("pkg-config xrender --cflags --libs")
if os.system("pkg-config --exists xi"):
print("Error: Xi library not found. Aborting.")
sys.exit(255)
env.ParseConfig("pkg-config xi --cflags --libs")
env.Append(CPPDEFINES=["X11_ENABLED"])
if env["vulkan"]:

View File

@ -36,7 +36,11 @@
#include "core/os/os.h"
#include "core/string/ustring.h"
#ifdef SOWRAP_ENABLED
#include "dbus-so_wrap.h"
#else
#include <dbus/dbus.h>
#endif
#include "core/variant/variant.h"
@ -124,12 +128,16 @@ uint32_t FreeDesktopPortalDesktop::get_appearance_color_scheme() {
}
FreeDesktopPortalDesktop::FreeDesktopPortalDesktop() {
#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
int dylibloader_verbose = 0;
#endif
unsupported = (initialize_dbus(dylibloader_verbose) != 0);
#else
unsupported = false;
#endif
}
#endif // DBUS_ENABLED

View File

@ -34,7 +34,11 @@
#include "core/config/project_settings.h"
#ifdef SOWRAP_ENABLED
#include "dbus-so_wrap.h"
#else
#include <dbus/dbus.h>
#endif
#define BUS_OBJECT_NAME "org.freedesktop.ScreenSaver"
#define BUS_OBJECT_PATH "/org/freedesktop/ScreenSaver"
@ -127,12 +131,16 @@ void FreeDesktopScreenSaver::uninhibit() {
}
FreeDesktopScreenSaver::FreeDesktopScreenSaver() {
#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
int dylibloader_verbose = 0;
#endif
unsupported = (initialize_dbus(dylibloader_verbose) != 0);
#else
unsupported = false;
#endif
}
#endif // DBUS_ENABLED

View File

@ -39,7 +39,11 @@
#include <unistd.h>
#ifdef UDEV_ENABLED
#ifdef SOWRAP_ENABLED
#include "libudev-so_wrap.h"
#else
#include <libudev.h>
#endif
#endif
#define LONG_BITS (sizeof(long) * 8)
@ -70,6 +74,7 @@ void JoypadLinux::Joypad::reset() {
JoypadLinux::JoypadLinux(Input *in) {
#ifdef UDEV_ENABLED
#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
@ -81,6 +86,7 @@ JoypadLinux::JoypadLinux(Input *in) {
} else {
print_verbose("JoypadLinux: udev enabled, but couldn't be loaded. Falling back to /dev/input to detect joypads.");
}
#endif
#else
print_verbose("JoypadLinux: udev disabled, parsing /dev/input to detect joypads.");
#endif

View File

@ -1083,12 +1083,16 @@ OS_LinuxBSD::OS_LinuxBSD() {
#endif
#ifdef FONTCONFIG_ENABLED
#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
int dylibloader_verbose = 0;
#endif
font_config_initialized = (initialize_fontconfig(dylibloader_verbose) == 0);
#else
font_config_initialized = true;
#endif
if (font_config_initialized) {
config = FcInitLoadConfigAndFonts();
if (!config) {

View File

@ -41,7 +41,11 @@
#include "servers/audio_server.h"
#ifdef FONTCONFIG_ENABLED
#ifdef SOWRAP_ENABLED
#include "fontconfig-so_wrap.h"
#else
#include <fontconfig/fontconfig.h>
#endif
#endif
class OS_LinuxBSD : public OS_Unix {

View File

@ -39,12 +39,18 @@ void TTS_Linux::speech_init_thread_func(void *p_userdata) {
TTS_Linux *tts = (TTS_Linux *)p_userdata;
if (tts) {
MutexLock thread_safe_method(tts->_thread_safe_);
#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
int dylibloader_verbose = 0;
#endif
if (initialize_speechd(dylibloader_verbose) == 0) {
if (initialize_speechd(dylibloader_verbose) != 0) {
print_verbose("Text-to-Speech: Cannot load Speech Dispatcher library!");
} else {
#else
{
#endif
CharString class_str;
String config_name = GLOBAL_GET("application/config/name");
if (config_name.length() == 0) {
@ -64,8 +70,6 @@ void TTS_Linux::speech_init_thread_func(void *p_userdata) {
} else {
print_verbose("Text-to-Speech: Cannot initialize Speech Dispatcher synthesizer!");
}
} else {
print_verbose("Text-to-Speech: Cannot load Speech Dispatcher library!");
}
}
}

View File

@ -39,7 +39,11 @@
#include "core/variant/array.h"
#include "servers/display_server.h"
#ifdef SOWRAP_ENABLED
#include "speechd-so_wrap.h"
#else
#include <libspeechd.h>
#endif
class TTS_Linux {
_THREAD_SAFE_CLASS_

View File

@ -5,6 +5,11 @@ Import("env")
source_files = [
"display_server_x11.cpp",
"key_mapping_x11.cpp",
]
if env["use_sowrap"]:
source_files.append(
[
"dynwrappers/xlib-so_wrap.c",
"dynwrappers/xcursor-so_wrap.c",
"dynwrappers/xinerama-so_wrap.c",
@ -13,6 +18,7 @@ source_files = [
"dynwrappers/xrender-so_wrap.c",
"dynwrappers/xext-so_wrap.c",
]
)
if env["vulkan"]:
source_files.append("vulkan_context_x11.cpp")

View File

@ -41,7 +41,13 @@
#include "thirdparty/glad/glad/gl.h"
#include "thirdparty/glad/glad/glx.h"
#ifdef SOWRAP_ENABLED
#include "dynwrappers/xlib-so_wrap.h"
#else
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif
#include <cstring>

View File

@ -1329,12 +1329,14 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
wd.xic = nullptr;
}
XDestroyWindow(x11_display, wd.x11_xim_window);
#ifdef XKB_ENABLED
if (xkb_loaded) {
if (wd.xkb_state) {
xkb_compose_state_unref(wd.xkb_state);
wd.xkb_state = nullptr;
}
}
#endif
XUnmapWindow(x11_display, wd.x11_window);
XDestroyWindow(x11_display, wd.x11_window);
@ -2942,11 +2944,13 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
XLookupString(&xkeyevent_no_mod, nullptr, 0, &keysym_keycode, nullptr);
String keysym;
#ifdef XKB_ENABLED
if (xkb_loaded) {
KeySym keysym_unicode_nm = 0; // keysym used to find unicode
XLookupString(&xkeyevent_no_mod, nullptr, 0, &keysym_unicode_nm, nullptr);
keysym = String::chr(xkb_keysym_to_utf32(xkb_keysym_to_upper(keysym_unicode_nm)));
}
#endif
// Meanwhile, XLookupString returns keysyms useful for unicode.
@ -3035,6 +3039,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
}
} while (status == XBufferOverflow);
#endif
#ifdef XKB_ENABLED
} else if (xkeyevent->type == KeyPress && wd.xkb_state && xkb_loaded) {
xkb_compose_feed_result res = xkb_compose_state_feed(wd.xkb_state, keysym_unicode);
if (res == XKB_COMPOSE_FEED_ACCEPTED) {
@ -3093,6 +3098,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
return;
}
}
#endif
}
/* Phase 2, obtain a Godot keycode from the keysym */
@ -4948,11 +4954,11 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
window_attributes_ime.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask;
wd.x11_xim_window = XCreateWindow(x11_display, wd.x11_window, 0, 0, 1, 1, 0, CopyFromParent, InputOnly, CopyFromParent, CWEventMask, &window_attributes_ime);
#ifdef XKB_ENABLED
if (dead_tbl && xkb_loaded) {
wd.xkb_state = xkb_compose_state_new(dead_tbl, XKB_COMPOSE_STATE_NO_FLAGS);
}
#endif
// Enable receiving notification when the window is initialized (MapNotify)
// so the focus can be set at the right time.
if (!wd.no_focus && !wd.is_popup) {
@ -5217,6 +5223,7 @@ static ::XIMStyle _get_best_xim_style(const ::XIMStyle &p_style_a, const ::XIMSt
DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Error &r_error) {
KeyMappingX11::initialize();
#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
@ -5231,9 +5238,9 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Can't load XCursor dynamically.");
}
#ifdef XKB_ENABLED
xkb_loaded = (initialize_xkbcommon(dylibloader_verbose) == 0);
#endif
if (initialize_xext(dylibloader_verbose) != 0) {
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Can't load Xext dynamically.");
@ -5258,7 +5265,13 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Can't load Xinput2 dynamically.");
}
#else
#ifdef XKB_ENABLED
xkb_loaded = true;
#endif
#endif
#ifdef XKB_ENABLED
if (xkb_loaded) {
xkb_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (xkb_ctx) {
@ -5275,6 +5288,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
dead_tbl = xkb_compose_table_new_from_locale(xkb_ctx, locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
}
}
#endif
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
@ -5717,16 +5731,19 @@ DisplayServerX11::~DisplayServerX11() {
wd.xic = nullptr;
}
XDestroyWindow(x11_display, wd.x11_xim_window);
#ifdef XKB_ENABLED
if (xkb_loaded) {
if (wd.xkb_state) {
xkb_compose_state_unref(wd.xkb_state);
wd.xkb_state = nullptr;
}
}
#endif
XUnmapWindow(x11_display, wd.x11_window);
XDestroyWindow(x11_display, wd.x11_window);
}
#ifdef XKB_ENABLED
if (xkb_loaded) {
if (dead_tbl) {
xkb_compose_table_unref(dead_tbl);
@ -5735,6 +5752,7 @@ DisplayServerX11::~DisplayServerX11() {
xkb_context_unref(xkb_ctx);
}
}
#endif
//destroy drivers
#if defined(VULKAN_ENABLED)

View File

@ -36,6 +36,8 @@
#include "servers/display_server.h"
#include "core/input/input.h"
#include "core/os/mutex.h"
#include "core/os/thread.h"
#include "core/templates/local_vector.h"
#include "drivers/alsa/audio_driver_alsa.h"
#include "drivers/alsamidi/midi_driver_alsamidi.h"
@ -69,6 +71,7 @@
#include <X11/Xutil.h>
#include <X11/keysym.h>
#ifdef SOWRAP_ENABLED
#include "dynwrappers/xlib-so_wrap.h"
#include "dynwrappers/xcursor-so_wrap.h"
@ -79,6 +82,25 @@
#include "dynwrappers/xrender-so_wrap.h"
#include "../xkbcommon-so_wrap.h"
#else
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xcursor/Xcursor.h>
#include <X11/extensions/XInput2.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/Xinerama.h>
#include <X11/extensions/Xrandr.h>
#include <X11/extensions/Xrender.h>
#include <X11/extensions/shape.h>
#ifdef XKB_ENABLED
#include <xkbcommon/xkbcommon-compose.h>
#include <xkbcommon/xkbcommon-keysyms.h>
#include <xkbcommon/xkbcommon.h>
#endif
#endif
typedef struct _xrr_monitor_info {
Atom name;
@ -142,7 +164,9 @@ class DisplayServerX11 : public DisplayServer {
bool ime_active = false;
bool ime_in_progress = false;
bool ime_suppress_next_keyup = false;
#ifdef XKB_ENABLED
xkb_compose_state *xkb_state = nullptr;
#endif
Size2i min_size;
Size2i max_size;
@ -186,9 +210,11 @@ class DisplayServerX11 : public DisplayServer {
Point2i im_selection;
String im_text;
#ifdef XKB_ENABLED
bool xkb_loaded = false;
xkb_context *xkb_ctx = nullptr;
xkb_compose_table *dead_tbl = nullptr;
#endif
HashMap<WindowID, WindowData> windows;

View File

@ -37,9 +37,22 @@
#include "core/os/os.h"
#include "core/templates/local_vector.h"
#include "dynwrappers/xext-so_wrap.h"
#ifdef SOWRAP_ENABLED
#include "dynwrappers/xlib-so_wrap.h"
#include "dynwrappers/xext-so_wrap.h"
#include "dynwrappers/xrender-so_wrap.h"
#else
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/Xrender.h>
#include <X11/extensions/shape.h>
#endif
#include "servers/display_server.h"
struct GLManager_X11_Private;