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