From 29058a09bbef0f249da39938efc2c460a11f7c15 Mon Sep 17 00:00:00 2001 From: Tianhao Chai Date: Thu, 12 Oct 2023 22:34:04 -0400 Subject: [PATCH] nvctrl: call XDefaultScreen for screen id (#1152) Calling nvctrl XNVCTRLIsNvScreen with X display ID used for screen id is a programmer error. For most common use cases, Gnome on X11 may launch user sessions on X display ":1" but still uses screen 0. Current code will always fail to find a correct display in this case, as both `IsNvScreen(":0", 0)` and `IsNvScreen(":1", 1)` returns false. Call XDefaultScreen with `struct Display *` to obtain the correct screen id, then use this id for `IsNvScreen()`. --- src/loaders/loader_x11.cpp | 8 ++++++++ src/loaders/loader_x11.h | 1 + src/nvctrl.cpp | 3 ++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/loaders/loader_x11.cpp b/src/loaders/loader_x11.cpp index 549424fc..dc599277 100644 --- a/src/loaders/loader_x11.cpp +++ b/src/loaders/loader_x11.cpp @@ -37,6 +37,14 @@ bool libx11_loader::Load(const std::string& library_name) { return false; } + XDefaultScreen = + reinterpret_castXDefaultScreen)>( + dlsym(library_, "XDefaultScreen")); + if (!XDefaultScreen) { + CleanUp(true); + return false; + } + XQueryKeymap = reinterpret_castXQueryKeymap)>( dlsym(library_, "XQueryKeymap")); diff --git a/src/loaders/loader_x11.h b/src/loaders/loader_x11.h index fedac4ce..8861985f 100644 --- a/src/loaders/loader_x11.h +++ b/src/loaders/loader_x11.h @@ -16,6 +16,7 @@ class libx11_loader { decltype(&::XOpenDisplay) XOpenDisplay; decltype(&::XCloseDisplay) XCloseDisplay; + decltype(&::XDefaultScreen) XDefaultScreen; decltype(&::XQueryKeymap) XQueryKeymap; decltype(&::XKeysymToKeycode) XKeysymToKeycode; decltype(&::XStringToKeysym) XStringToKeysym; diff --git a/src/nvctrl.cpp b/src/nvctrl.cpp index 6ceba3af..ca565ceb 100644 --- a/src/nvctrl.cpp +++ b/src/nvctrl.cpp @@ -26,7 +26,8 @@ static bool find_nv_x11(libnvctrl_loader& nvctrl, Display*& dpy) snprintf(buf, sizeof(buf), ":%d", i); Display *d = libx11->XOpenDisplay(buf); if (d) { - if (nvctrl.XNVCTRLIsNvScreen(d, i)) { + int s = libx11->XDefaultScreen(d); + if (nvctrl.XNVCTRLIsNvScreen(d, s)) { dpy = d; SPDLOG_DEBUG("XNVCtrl is using display {}", buf); return true;