Skip to content

Commit

Permalink
gap: Dynamically load xfixes (#1262)
Browse files Browse the repository at this point in the history
* net: Undef SECUR_LOAD_SYM

* core,snd: Fix missing undefs

* gap: Dynamically load xfixes extension

* gap: Remove dependency on xfixes header

* gap: Remove stdlib header
  • Loading branch information
BastianBlokland authored Feb 4, 2025
1 parent 0c839bc commit 072f169
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 46 deletions.
3 changes: 1 addition & 2 deletions .github/actions/prepare-ubuntu/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ runs:
shell: bash
run: |
sudo apt install \
libxcb1-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libxcb-xfixes0-dev \
libxcb-randr0-dev libxcb-render0-dev
libxcb1-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libxcb-randr0-dev libxcb-render0-dev
- name: install-vulkan
shell: bash
Expand Down
11 changes: 0 additions & 11 deletions cmake/modules/Findxcb-xfixes.cmake

This file was deleted.

2 changes: 2 additions & 0 deletions libs/core/src/symbol_pal_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ static bool sym_dbg_dw_load(SymDbg* dbg, Allocator* alloc) {
DW_LOAD_SYM(elf_getphdrnum);
DW_LOAD_SYM(gelf_getphdr);

#undef DW_LOAD_SYM

return true;
}

Expand Down
2 changes: 2 additions & 0 deletions libs/core/src/symbol_pal_win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ static bool sym_dbg_lib_load(SymDbg* dbg, Allocator* alloc) {
DBG_LOAD_SYM(SymLoadModuleEx);
DBG_LOAD_SYM(SymEnumSymbolsEx);

#undef DBG_LOAD_SYM

return true;
}

Expand Down
6 changes: 2 additions & 4 deletions libs/gap/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,21 @@ target_link_libraries(lib_gap PRIVATE lib_log lib_asset)
#
# On linux use the xcb (https://xcb.freedesktop.org/) bindings for the x window server.
# For debian based systems:
# apt install libxcb1-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libxcb-xfixes0-dev libxcb-randr0-dev libxcb-render0-dev
# apt install libxcb1-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libxcb-randr0-dev libxcb-render0-dev
#
if(${VOLO_PLATFORM} STREQUAL "linux")

message(STATUS "> Configuring xcb (with xkb, xkbcommon, xkbcommon-x11, xfixes, randr and render extensions) package")
message(STATUS "> Configuring xcb (with xkb, xkbcommon, xkbcommon-x11, randr and render extensions) package")
find_package(xcb REQUIRED)
find_package(xcb-randr REQUIRED)
find_package(xcb-render REQUIRED)
find_package(xcb-xfixes REQUIRED)
find_package(xcb-xkb REQUIRED)
find_package(xkbcommon REQUIRED)
find_package(xkbcommon-x11 REQUIRED)
target_link_libraries(lib_gap PRIVATE
xcb
xcb-randr
xcb-render
xcb-xfixes
xcb-xkb
xkbcommon
xkbcommon-x11
Expand Down
84 changes: 56 additions & 28 deletions libs/gap/src/pal_linux_xcb.c
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
#include "core_array.h"
#include "core_diag.h"
#include "core_dynlib.h"
#include "core_dynstring.h"
#include "core_math.h"
#include "log_logger.h"

#include "pal_internal.h"

#include <stdlib.h>
#include <xcb/randr.h>
#include <xcb/render.h>
#include <xcb/xcb.h>
#include <xcb/xfixes.h>
#include <xcb/xkb.h>
#include <xkbcommon/xkbcommon-x11.h>

void SYS_DECL free(void*); // free from stdlib, xcb allocates various structures for us to free.

/**
* X11 client implementation using the xcb library.
* Optionally uses the xkb, xkbcommon, xkbcommon-x11, xfixes, randr and render extensions.
Expand All @@ -35,11 +36,22 @@

#define pal_xcb_call_void(_CON_, _FUNC_, _ERR_) _FUNC_##_reply((_CON_), _FUNC_(_CON_), (_ERR_))

typedef unsigned int XcbCookie;

typedef struct {
DynLib* lib;
// clang-format off
XcbCookie (SYS_DECL* query_version)(xcb_connection_t*, uint32_t majorVersion, uint32_t minorVersion);
void* (SYS_DECL* query_version_reply)(xcb_connection_t*, XcbCookie, xcb_generic_error_t**);
XcbCookie (SYS_DECL* show_cursor)(xcb_connection_t*, xcb_window_t);
XcbCookie (SYS_DECL* hide_cursor)(xcb_connection_t*, xcb_window_t);
// clang-format on
} XcbXFixes;

typedef enum {
GapPalXcbExtFlags_Xkb = 1 << 0,
GapPalXcbExtFlags_XFixes = 1 << 1,
GapPalXcbExtFlags_Randr = 1 << 2,
GapPalXcbExtFlags_Render = 1 << 3,
GapPalXcbExtFlags_Randr = 1 << 1,
GapPalXcbExtFlags_Render = 1 << 2,
} GapPalXcbExtFlags;

typedef enum {
Expand Down Expand Up @@ -82,6 +94,8 @@ struct sGapPal {
u8 randrFirstEvent;
GapPalFlags flags;

XcbXFixes xfixes;

struct xkb_context* xkbContext;
i32 xkbDeviceId;
struct xkb_keymap* xkbKeymap;
Expand Down Expand Up @@ -493,29 +507,41 @@ static bool pal_xkb_init(GapPal* pal) {
/**
* Initialize xfixes extension, contains various utilities.
*/
static bool pal_xfixes_init(GapPal* pal) {
xcb_generic_error_t* err = null;
xcb_xfixes_query_version_reply_t* reply = pal_xcb_call(
pal->xcbCon,
xcb_xfixes_query_version,
&err,
XCB_XFIXES_MAJOR_VERSION,
XCB_XFIXES_MINOR_VERSION);

if (UNLIKELY(err)) {
log_w("Xcb failed to initialize the xfixes ext", log_param("error", fmt_int(err->error_code)));
free(reply);
static bool pal_xfixes_init(GapPal* pal, XcbXFixes* out) {
DynLibResult loadRes = dynlib_load(pal->alloc, string_lit("libxcb-xfixes.so"), &out->lib);
if (loadRes != DynLibResult_Success) {
const String err = dynlib_result_str(loadRes);
log_w("Failed to load xfixes library ('libxcb-xfixes.so')", log_param("err", fmt_text(err)));
return false;
}

MAYBE_UNUSED const u16 versionMajor = reply->major_version;
MAYBE_UNUSED const u16 versionMinor = reply->minor_version;
#define XFIXES_LOAD_SYM(_NAME_) \
do { \
const String symName = string_lit("xcb_xfixes_" #_NAME_); \
out->_NAME_ = dynlib_symbol(out->lib, symName); \
if (!out->_NAME_) { \
log_w("XFixes symbol '{}' missing", log_param("sym", fmt_text(symName))); \
return false; \
} \
} while (false)

XFIXES_LOAD_SYM(query_version);
XFIXES_LOAD_SYM(query_version_reply);
XFIXES_LOAD_SYM(show_cursor);
XFIXES_LOAD_SYM(hide_cursor);

#undef XFIXES_LOAD_SYM

xcb_generic_error_t* err = null;
void* reply = pal_xcb_call(pal->xcbCon, out->query_version, &err, 5, 0);
free(reply);

log_i(
"Xcb initialized the xfixes extension",
log_param("version", fmt_list_lit(fmt_int(versionMajor), fmt_int(versionMinor))));
if (UNLIKELY(err)) {
log_w("Failed to initialize Xcb xfixes", log_param("error", fmt_int(err->error_code)));
return false;
}

log_i("Initialized Xcb xfixes", log_param("path", fmt_path(dynlib_path(out->lib))));
return true;
}

Expand Down Expand Up @@ -630,9 +656,7 @@ static void pal_init_extensions(GapPal* pal) {
if (pal_xkb_init(pal)) {
pal->extensions |= GapPalXcbExtFlags_Xkb;
}
if (pal_xfixes_init(pal)) {
pal->extensions |= GapPalXcbExtFlags_XFixes;
}
pal_xfixes_init(pal, &pal->xfixes);
if (pal_randr_init(pal, &pal->randrFirstEvent)) {
pal->extensions |= GapPalXcbExtFlags_Randr;
}
Expand Down Expand Up @@ -1092,6 +1116,10 @@ void gap_pal_destroy(GapPal* pal) {
}
dynarray_for_t(&pal->displays, GapPalDisplay, d) { string_maybe_free(g_allocHeap, d->name); }

if (pal->xfixes.lib) {
dynlib_destroy(pal->xfixes.lib);
}

if (pal->xkbContext) {
xkb_context_unref(pal->xkbContext);
}
Expand Down Expand Up @@ -1616,17 +1644,17 @@ void gap_pal_window_resize(
}

void gap_pal_window_cursor_hide(GapPal* pal, const GapWindowId windowId, const bool hidden) {
if (!(pal->extensions & GapPalXcbExtFlags_XFixes)) {
if (!pal->xfixes.hide_cursor || !pal->xfixes.show_cursor) {
log_w("Failed to update cursor visibility: XFixes extension not available");
return;
}

if (hidden && !(pal->flags & GapPalFlags_CursorHidden)) {
xcb_xfixes_hide_cursor(pal->xcbCon, (xcb_window_t)windowId);
pal->xfixes.hide_cursor(pal->xcbCon, (xcb_window_t)windowId);
pal->flags |= GapPalFlags_CursorHidden;

} else if (!hidden && pal->flags & GapPalFlags_CursorHidden) {
xcb_xfixes_show_cursor(pal->xcbCon, (xcb_window_t)windowId);
pal->xfixes.show_cursor(pal->xcbCon, (xcb_window_t)windowId);
pal->flags &= ~GapPalFlags_CursorHidden;
}
}
Expand Down
2 changes: 2 additions & 0 deletions libs/net/src/tls_schannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ static bool net_schannel_init(NetSChannel* schannel, Allocator* alloc) {
SECUR_LOAD_SYM(EncryptMessage);
SECUR_LOAD_SYM(DecryptMessage);

#undef SECUR_LOAD_SYM

if (!net_schannel_create_cred(schannel, false /* noVerify */, &schannel->creds)) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion libs/snd/src/device_pal_linux_alsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ static bool alsa_lib_init(AlsaLib* lib, Allocator* alloc) {
ALSA_LOAD_SYM(pcm_hw_params_set_periods_near);
ALSA_LOAD_SYM(pcm_hw_params_set_period_size_near);

#undef ALSA_LIB_SYM
#undef ALSA_LOAD_SYM
return true;
}

Expand Down

0 comments on commit 072f169

Please sign in to comment.