xcbWindow: Group xcbXorg DLL state together

This commit is contained in:
2025-07-24 06:14:08 -04:00
parent 1e17b83061
commit b28239550e
+32 -28
View File
@@ -12,15 +12,19 @@
#include "../../commonLibs/xcbXorg/xcbXorg.h"
// Function pointers to API entry points exported by libxcbXorg.
struct XcbXorgFunctions {
get_or_create_connection_fn* getOrCreateConnection = nullptr;
cleanup_connections_fn* cleanupConnections = nullptr;
find_window_by_id_fn* findWindowById = nullptr;
find_window_by_name_fn* findWindowByName = nullptr;
struct XcbXorgDllState
{
struct XcbXorgFunctions
{
get_or_create_connection_fn* getOrCreateConnection = nullptr;
cleanup_connections_fn* cleanupConnections = nullptr;
find_window_by_id_fn* findWindowById = nullptr;
find_window_by_name_fn* findWindowByName = nullptr;
} fns;
void* dlopenHandle = nullptr;
};
static void* g_xcbXorgHandle = nullptr;
static XcbXorgFunctions xcbXorgFns;
static XcbXorgDllState xcbXorg;
// Salmanoff hooks, obtained from SMO_GET_SENSE_API_DESC_FN_NAME().
static const smo::sense_api::SalmanoffCallbacks* smoHooksPtr = nullptr;
@@ -53,8 +57,8 @@ AttachedWindow::AttachedWindow(const smo::device::SenseDeviceSpec& spec)
: deviceSpec(spec), xcbConnection(nullptr)
{
// Validate required function pointers are available
if (!xcbXorgFns.getOrCreateConnection ||
!xcbXorgFns.findWindowById || !xcbXorgFns.findWindowByName)
if (!xcbXorg.fns.getOrCreateConnection ||
!xcbXorg.fns.findWindowById || !xcbXorg.fns.findWindowByName)
{
throw std::runtime_error("xcbWindow:" + std::string(__func__) +
": Required xcbXorg function pointers not available");
@@ -66,7 +70,7 @@ AttachedWindow::AttachedWindow(const smo::device::SenseDeviceSpec& spec)
// Get connection from libxcbXorg
std::shared_ptr<xcb_xorg::XcbConnection> conn =
(*xcbXorgFns.getOrCreateConnection)(
(*xcbXorg.fns.getOrCreateConnection)(
windowSelector.display, windowSelector.screen);
xcbConnection = conn.get();
@@ -78,13 +82,13 @@ AttachedWindow::AttachedWindow(const smo::device::SenseDeviceSpec& spec)
if (windowSelector.matchType == xcb_xorg::window_search::MatchType::ID)
{
foundWindow = (*xcbXorgFns.findWindowById)(
foundWindow = (*xcbXorg.fns.findWindowById)(
xcbConnection, screen->root,
windowSelector.windowId);
}
else
{
foundWindow = (*xcbXorgFns.findWindowByName)(
foundWindow = (*xcbXorg.fns.findWindowByName)(
xcbConnection, screen->root,
windowSelector.windowName, actualWindowName,
windowSelector.matchType);
@@ -230,29 +234,29 @@ static int xcbWindow_initializeInd(void)
// Try to load libxcbXorg using the search path hook
auto libPath = smoHooksPtr->searchForLibInSmoSearchPaths("libxcbXorg.so");
g_xcbXorgHandle = dlopen(
xcbXorg.dlopenHandle = dlopen(
libPath.value_or("libxcbXorg.so").c_str(),
RTLD_LAZY);
if (!g_xcbXorgHandle)
if (!xcbXorg.dlopenHandle)
{
throw std::runtime_error("xcbWindow:" + std::string(__func__) +
": Failed to load libxcbXorg: " + std::string(dlerror()));
}
// Fill in function pointers from libxcbXorg.
xcbXorgFns.getOrCreateConnection =
xcbXorg.fns.getOrCreateConnection =
reinterpret_cast<get_or_create_connection_fn*>(
dlsym(g_xcbXorgHandle, "xcb_xorg_get_or_create_connection"));
xcbXorgFns.cleanupConnections = reinterpret_cast<cleanup_connections_fn*>(
dlsym(g_xcbXorgHandle, "xcb_xorg_cleanup_connections"));
xcbXorgFns.findWindowById = reinterpret_cast<find_window_by_id_fn*>(
dlsym(g_xcbXorgHandle, "xcb_xorg_find_window_by_id"));
xcbXorgFns.findWindowByName = reinterpret_cast<find_window_by_name_fn*>(
dlsym(g_xcbXorgHandle, "xcb_xorg_find_window_by_name"));
dlsym(xcbXorg.dlopenHandle, "xcb_xorg_get_or_create_connection"));
xcbXorg.fns.cleanupConnections = reinterpret_cast<cleanup_connections_fn*>(
dlsym(xcbXorg.dlopenHandle, "xcb_xorg_cleanup_connections"));
xcbXorg.fns.findWindowById = reinterpret_cast<find_window_by_id_fn*>(
dlsym(xcbXorg.dlopenHandle, "xcb_xorg_find_window_by_id"));
xcbXorg.fns.findWindowByName = reinterpret_cast<find_window_by_name_fn*>(
dlsym(xcbXorg.dlopenHandle, "xcb_xorg_find_window_by_name"));
if (!xcbXorgFns.getOrCreateConnection || !xcbXorgFns.cleanupConnections
|| !xcbXorgFns.findWindowById || !xcbXorgFns.findWindowByName)
if (!xcbXorg.fns.getOrCreateConnection || !xcbXorg.fns.cleanupConnections
|| !xcbXorg.fns.findWindowById || !xcbXorg.fns.findWindowByName)
{
throw std::runtime_error(
std::string("xcbWindow:") + __func__ +
@@ -266,11 +270,11 @@ static int xcbWindow_finalizeInd(void)
{
g_attachedWindows.clear();
if (g_xcbXorgHandle)
if (xcbXorg.dlopenHandle)
{
dlclose(g_xcbXorgHandle);
g_xcbXorgHandle = nullptr;
xcbXorgFns = { nullptr, nullptr, nullptr, nullptr };
dlclose(xcbXorg.dlopenHandle);
xcbXorg.dlopenHandle = nullptr;
xcbXorg.fns = { nullptr, nullptr, nullptr, nullptr };
}
return 0;