#include "loader_nvctrl.h" #include #include #include // Put these sanity checks here so that they fire at most once // (to avoid cluttering the build output). #if !defined(LIBRARY_LOADER_NVCTRL_H_DLOPEN) && !defined(LIBRARY_LOADER_NVCTRL_H_DT_NEEDED) #error neither LIBRARY_LOADER_NVCTRL_H_DLOPEN nor LIBRARY_LOADER_NVCTRL_H_DT_NEEDED defined #endif #if defined(LIBRARY_LOADER_NVCTRL_H_DLOPEN) && defined(LIBRARY_LOADER_NVCTRL_H_DT_NEEDED) #error both LIBRARY_LOADER_NVCTRL_H_DLOPEN and LIBRARY_LOADER_NVCTRL_H_DT_NEEDED defined #endif static std::unique_ptr libnvctrl_; libnvctrl_loader& get_libnvctrl_loader() { if (!libnvctrl_) libnvctrl_ = std::make_unique("libXNVCtrl.so.0"); return *libnvctrl_.get(); } libnvctrl_loader::libnvctrl_loader() : loaded_(false) { } libnvctrl_loader::~libnvctrl_loader() { CleanUp(loaded_); } bool libnvctrl_loader::Load(const std::string& library_name) { if (loaded_) { return false; } #if defined(LIBRARY_LOADER_NVCTRL_H_DLOPEN) library_ = dlopen(library_name.c_str(), RTLD_LAZY); if (!library_) { spdlog::error("Failed to open " MANGOHUD_ARCH " {}: {}", library_name, dlerror()); return false; } XNVCTRLIsNvScreen = reinterpret_castXNVCTRLIsNvScreen)>( dlsym(library_, "XNVCTRLIsNvScreen")); if (!XNVCTRLIsNvScreen) { CleanUp(true); return false; } XNVCTRLQueryVersion = reinterpret_castXNVCTRLQueryVersion)>( dlsym(library_, "XNVCTRLQueryVersion")); if (!XNVCTRLQueryVersion) { CleanUp(true); return false; } XNVCTRLQueryAttribute = reinterpret_castXNVCTRLQueryAttribute)>( dlsym(library_, "XNVCTRLQueryAttribute")); if (!XNVCTRLQueryAttribute) { CleanUp(true); return false; } XNVCTRLQueryTargetStringAttribute = reinterpret_castXNVCTRLQueryTargetStringAttribute)>( dlsym(library_, "XNVCTRLQueryTargetStringAttribute")); if (!XNVCTRLQueryTargetStringAttribute) { CleanUp(true); return false; } XNVCTRLQueryTargetAttribute64 = reinterpret_castXNVCTRLQueryTargetAttribute64)>( dlsym(library_, "XNVCTRLQueryTargetAttribute64")); if (!XNVCTRLQueryTargetAttribute64) { CleanUp(true); return false; } #endif #if defined(LIBRARY_LOADER_NVCTRL_H_DT_NEEDED) XNVCTRLQueryVersion = &::XNVCTRLQueryVersion; XNVCTRLQueryAttribute = &::XNVCTRLQueryAttribute; #endif loaded_ = true; return true; } void libnvctrl_loader::CleanUp(bool unload) { #if defined(LIBRARY_LOADER_NVCTRL_H_DLOPEN) if (unload) { dlclose(library_); library_ = NULL; } #endif loaded_ = false; XNVCTRLQueryVersion = NULL; XNVCTRLQueryAttribute = NULL; }