mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2026-06-29 01:54:20 +03:00
MangoHud: rename to LibraryUtils
It handles more than mangohud Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
parent
248eb13ab9
commit
327a554d42
5 changed files with 20 additions and 20 deletions
173
launcher/LibraryUtils.cpp
Normal file
173
launcher/LibraryUtils.cpp
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PrismLauncher - Minecraft Launcher
|
||||
* Copyright (C) 2022 Jan Drögehoff <sentrycraft123@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QSysInfo>
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "Json.h"
|
||||
#include "LibraryUtils.h"
|
||||
|
||||
#ifdef __GLIBC__
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#define UNDEF_GNU_SOURCE
|
||||
#endif
|
||||
#include <dlfcn.h>
|
||||
#include <linux/limits.h>
|
||||
#endif
|
||||
|
||||
namespace LibraryUtils {
|
||||
|
||||
QString findMangoHud()
|
||||
{
|
||||
/**
|
||||
* Guess MangoHud install location by searching for vulkan layers in this order:
|
||||
*
|
||||
* $VK_LAYER_PATH
|
||||
* $XDG_DATA_DIRS (/usr/local/share/:/usr/share/)
|
||||
* $XDG_DATA_HOME (~/.local/share)
|
||||
* /etc
|
||||
* $XDG_CONFIG_DIRS (/etc/xdg)
|
||||
* $XDG_CONFIG_HOME (~/.config)
|
||||
*
|
||||
* @returns Absolute path of libMangoHud.so if found and empty QString otherwise.
|
||||
*/
|
||||
QStringList vkLayerList;
|
||||
{
|
||||
QString home = QDir::homePath();
|
||||
|
||||
QString vkLayerPath = qEnvironmentVariable("VK_LAYER_PATH");
|
||||
if (!vkLayerPath.isEmpty()) {
|
||||
vkLayerList << vkLayerPath;
|
||||
}
|
||||
|
||||
QStringList xdgDataDirs = qEnvironmentVariable("XDG_DATA_DIRS", "/usr/local/share/:/usr/share/").split(QLatin1String(":"));
|
||||
for (QString dir : xdgDataDirs) {
|
||||
vkLayerList << FS::PathCombine(dir, "vulkan", "implicit_layer.d");
|
||||
}
|
||||
|
||||
QString xdgDataHome = qEnvironmentVariable("XDG_DATA_HOME");
|
||||
if (xdgDataHome.isEmpty()) {
|
||||
xdgDataHome = FS::PathCombine(home, ".local", "share");
|
||||
}
|
||||
vkLayerList << FS::PathCombine(xdgDataHome, "vulkan", "implicit_layer.d");
|
||||
|
||||
vkLayerList << "/etc";
|
||||
|
||||
QStringList xdgConfigDirs = qEnvironmentVariable("XDG_CONFIG_DIRS", "/etc/xdg").split(QLatin1String(":"));
|
||||
for (QString dir : xdgConfigDirs) {
|
||||
vkLayerList << FS::PathCombine(dir, "vulkan", "implicit_layer.d");
|
||||
}
|
||||
|
||||
QString xdgConfigHome = qEnvironmentVariable("XDG_CONFIG_HOME");
|
||||
if (xdgConfigHome.isEmpty()) {
|
||||
xdgConfigHome = FS::PathCombine(home, ".config");
|
||||
}
|
||||
vkLayerList << FS::PathCombine(xdgConfigHome, "vulkan", "implicit_layer.d");
|
||||
}
|
||||
|
||||
for (const QString& vkLayer : vkLayerList) {
|
||||
// prefer to use architecture specific vulkan layers
|
||||
QString currentArch = QSysInfo::currentCpuArchitecture();
|
||||
|
||||
if (currentArch == "arm64") {
|
||||
currentArch = "aarch64";
|
||||
}
|
||||
|
||||
QStringList manifestNames = { QString("MangoHud.%1.json").arg(currentArch), "MangoHud.json" };
|
||||
|
||||
QString filePath{};
|
||||
for (const QString& manifestName : manifestNames) {
|
||||
QString tryPath = FS::PathCombine(vkLayer, manifestName);
|
||||
if (QFile::exists(tryPath)) {
|
||||
filePath = tryPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (filePath.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
auto conf = Json::requireDocument(filePath, vkLayer);
|
||||
auto confObject = Json::requireObject(conf, vkLayer);
|
||||
auto layer = confObject["layer"].toObject();
|
||||
QString libraryName = layer["library_path"].toString();
|
||||
|
||||
if (libraryName.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (QFileInfo(libraryName).isAbsolute()) {
|
||||
return libraryName;
|
||||
}
|
||||
|
||||
#ifdef __GLIBC__
|
||||
// Check whether mangohud is usable on a glibc based system
|
||||
QString libraryPath = find(libraryName);
|
||||
if (!libraryPath.isEmpty()) {
|
||||
return libraryPath;
|
||||
}
|
||||
#else
|
||||
// Without glibc return recorded shared library as-is.
|
||||
return libraryName;
|
||||
#endif
|
||||
} catch (const Exception& e) {
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QString find(QString libName)
|
||||
{
|
||||
#ifdef __GLIBC__
|
||||
const char* library = libName.toLocal8Bit().constData();
|
||||
|
||||
void* handle = dlopen(library, RTLD_NOW);
|
||||
if (!handle) {
|
||||
qCritical() << "dlopen() failed:" << dlerror();
|
||||
return {};
|
||||
}
|
||||
|
||||
char path[PATH_MAX];
|
||||
if (dlinfo(handle, RTLD_DI_ORIGIN, path) == -1) {
|
||||
qCritical() << "dlinfo() failed:" << dlerror();
|
||||
dlclose(handle);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto fullPath = FS::PathCombine(QString(path), libName);
|
||||
|
||||
dlclose(handle);
|
||||
return fullPath;
|
||||
#else
|
||||
qWarning() << "LibraryUtils::find is not implemented on this platform";
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
} // namespace LibraryUtils
|
||||
|
||||
#ifdef UNDEF_GNU_SOURCE
|
||||
#undef _GNU_SOURCE
|
||||
#undef UNDEF_GNU_SOURCE
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue