Compare commits
No commits in common. 'master' and 'v0.7.0-rc1' have entirely different histories.
master
...
v0.7.0-rc1
@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: FlightlessMango
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: https://www.paypal.me/flightlessmango
|
@ -1,58 +1,35 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$#" -eq 0 ]; then
|
||||
programname=$(basename "$0")
|
||||
echo "ERROR: No program supplied"
|
||||
echo
|
||||
echo "Usage: $programname <program>"
|
||||
exit 1
|
||||
programname=`basename "$0"`
|
||||
echo "ERROR: No program supplied"
|
||||
echo
|
||||
echo "Usage: $programname <program>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Add exe names newline separated to the string to disable LD_PRELOAD
|
||||
DISABLE_LD_PRELOAD="cs2.sh
|
||||
"
|
||||
|
||||
MANGOHUD_LIB_NAME="@ld_libdir_mangohud@libMangoHud_opengl.so"
|
||||
|
||||
if [ "$1" = "--dlsym" ]; then
|
||||
MANGOHUD_LIB_NAME="@ld_libdir_mangohud@libMangoHud_dlsym.so:${MANGOHUD_LIB_NAME}"
|
||||
shift # shift will only be executed if $1 is "--dlsym"
|
||||
elif [ "$MANGOHUD_DLSYM" = "1" ]; then
|
||||
MANGOHUD_LIB_NAME="@ld_libdir_mangohud@libMangoHud_dlsym.so:${MANGOHUD_LIB_NAME}"
|
||||
MANGOHUD_LIB_NAME="@ld_libdir_mangohud@libMangoHud_dlsym.so:${MANGOHUD_LIB_NAME}"
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ "$1" = "--version" ]; then
|
||||
echo @version@
|
||||
exit 0
|
||||
echo @version@
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# grab all arguments from command_line
|
||||
command_line="$*"
|
||||
# flag for disable_preload
|
||||
disable_preload=false
|
||||
# Make sure we don't append mangohud lib multiple times
|
||||
# otherwise this could cause issues with steam runtime
|
||||
case ":${LD_PRELOAD-}:" in
|
||||
(*:$MANGOHUD_LIB_NAME:*)
|
||||
;;
|
||||
(*)
|
||||
# Preload using the plain filenames of the libs, the dynamic linker will
|
||||
# figure out whether the 32 or 64 bit version should be used
|
||||
LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}${MANGOHUD_LIB_NAME}"
|
||||
esac
|
||||
|
||||
# Check if the script name or any of the executables in DISABLE_LD_PRELOAD are in the command line
|
||||
for exe in $DISABLE_LD_PRELOAD; do
|
||||
if echo "$command_line" | grep -q "$exe"; then
|
||||
disable_preload=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$disable_preload" = true ]; then
|
||||
exec env MANGOHUD=1 "$@"
|
||||
else
|
||||
# Make sure we don't append mangohud lib multiple times
|
||||
# otherwise, this could cause issues with the steam runtime
|
||||
case ":${LD_PRELOAD-}:" in
|
||||
(*:$MANGOHUD_LIB_NAME:*)
|
||||
;;
|
||||
(*)
|
||||
# Preload using the plain filenames of the libs, the dynamic linker will
|
||||
# figure out whether the 32 or 64 bit version should be used
|
||||
LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}${MANGOHUD_LIB_NAME}"
|
||||
esac
|
||||
|
||||
exec env MANGOHUD=1 LD_PRELOAD="${LD_PRELOAD}" "$@"
|
||||
fi
|
||||
exec env MANGOHUD=1 LD_PRELOAD="${LD_PRELOAD}" "$@"
|
||||
|
@ -1,7 +1,7 @@
|
||||
DEPS_ARCH="gcc,meson,pkgconf,python-mako,glslang,libglvnd,lib32-libglvnd,libxnvctrl,libdrm,python-numpy,python-matplotlib,libxkbcommon"
|
||||
DEPS_FEDORA="meson,gcc,gcc-c++,libX11-devel,glslang,python3-mako,mesa-libGL-devel,libXNVCtrl-devel,dbus-devel,python3-numpy,python3-matplotlib,libstdc++-static,libstdc++-static.i686,libxkbcommon-devel,wayland-devel"
|
||||
DEPS_DEBIAN="gcc,g++,gcc-multilib,g++-multilib,ninja-build,python3-pip,python3-setuptools,python3-wheel,pkg-config,mesa-common-dev,libx11-dev,libxnvctrl-dev,libdbus-1-dev,python3-numpy,python3-matplotlib,libxkbcommon-dev,libxkbcommon-dev:i386,libwayland-dev,libwayland-dev:i386"
|
||||
DEPS_SOLUS="mesalib-32bit-devel,glslang,libstdc++-32bit,glibc-32bit-devel,mako,numpy,matplotlib,libxkbcommon-devel"
|
||||
DEPS_ARCH="gcc,meson,pkgconf,python-mako,glslang,libglvnd,lib32-libglvnd,libxnvctrl,libdrm,python-numpy,python-matplotlib"
|
||||
DEPS_FEDORA="meson,gcc,gcc-c++,libX11-devel,glslang,python3-mako,mesa-libGL-devel,libXNVCtrl-devel,dbus-devel,python3-numpy,python3-matplotlib,libstdc++-static"
|
||||
DEPS_DEBIAN="gcc,g++,gcc-multilib,g++-multilib,ninja-build,python3-pip,python3-setuptools,python3-wheel,pkg-config,mesa-common-dev,libx11-dev,libxnvctrl-dev,libdbus-1-dev,python3-numpy,python3-matplotlib"
|
||||
DEPS_SOLUS="mesalib-32bit-devel,glslang,libstdc++-32bit,glibc-32bit-devel,mako,numpy,matplotlib"
|
||||
|
||||
DEPS_SUSE="gcc-c++,gcc-c++-32bit,libpkgconf-devel,ninja,python3-pip,python3-Mako,libX11-devel,glslang-devel,glibc-devel,glibc-devel-32bit,libstdc++-devel,libstdc++-devel-32bit,Mesa-libGL-devel,dbus-1-devel,python-numpy,python-matplotlib,libxkbcommon-devel"
|
||||
DEPS_SUSE="gcc-c++,gcc-c++-32bit,libpkgconf-devel,ninja,python3-pip,python3-Mako,libX11-devel,glslang-devel,glibc-devel,glibc-devel-32bit,libstdc++-devel,libstdc++-devel-32bit,Mesa-libGL-devel,dbus-1-devel,python-numpy,python-matplotlib"
|
||||
DEPS_SUSE_EXTRA="libXNVCtrl-devel"
|
||||
|
@ -1,225 +0,0 @@
|
||||
#include "device.h"
|
||||
#include <filesystem.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace fs = ghc::filesystem;
|
||||
using namespace std;
|
||||
std::mutex device_lock;
|
||||
std::vector<device_batt> device_data;
|
||||
std::vector<std::string> list;
|
||||
bool device_found = false;
|
||||
bool check_gamepad = false;
|
||||
bool check_mouse = false;
|
||||
int device_count = 0;
|
||||
int xbox_count = 0;
|
||||
int ds4_count = 0;
|
||||
int ds5_count = 0;
|
||||
int switch_count = 0;
|
||||
int bitdo_count = 0;
|
||||
int logi_count = 0; //Logitech devices, mice & keyboards etc.
|
||||
int shield_count = 0;
|
||||
|
||||
std::string xbox_paths [2]{"gip","xpadneo"};
|
||||
|
||||
static bool operator<(const device_batt& a, const device_batt& b)
|
||||
{
|
||||
return a.name < b.name;
|
||||
}
|
||||
|
||||
|
||||
void device_update(const struct overlay_params& params){
|
||||
std::unique_lock<std::mutex> l(device_lock);
|
||||
fs::path path("/sys/class/power_supply");
|
||||
list.clear();
|
||||
xbox_count = 0;
|
||||
ds4_count = 0;
|
||||
ds5_count = 0;
|
||||
switch_count = 0;
|
||||
bitdo_count = 0;
|
||||
shield_count = 0;
|
||||
for (auto &p : fs::directory_iterator(path)) {
|
||||
string fileName = p.path().filename();
|
||||
//Gamepads
|
||||
if (std::find(params.device_battery.begin(), params.device_battery.end(), "gamepad") != params.device_battery.end()){
|
||||
check_gamepad = true;
|
||||
//CHECK XONE AND XPADNEO DEVICES
|
||||
for (string n : xbox_paths ) {
|
||||
if (fileName.find(n) != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
xbox_count += 1;
|
||||
}
|
||||
}
|
||||
//CHECK FOR DUAL SHOCK 4 DEVICES
|
||||
if (fileName.find("sony_controller") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
ds4_count +=1 ;
|
||||
}
|
||||
if (fileName.find("ps-controller") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
ds5_count +=1 ;
|
||||
}
|
||||
//CHECK FOR NINTENDO SWITCH DEVICES
|
||||
if (fileName.find("nintendo_switch_controller") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
switch_count += 1;
|
||||
}
|
||||
//CHECK * BITDO DEVICES
|
||||
if (fileName.find("hid-e4") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
bitdo_count += 1;
|
||||
}
|
||||
//CHECK NVIDIA SHIELD DEVICES
|
||||
if (fileName.find("thunderstrike") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
shield_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Mice and Keyboards
|
||||
//CHECK LOGITECH DEVICES
|
||||
if (std::find(params.device_battery.begin(), params.device_battery.end(), "mouse") != params.device_battery.end()) {
|
||||
check_mouse = true;
|
||||
if (fileName.find("hidpp_battery") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
device_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void device_info () {
|
||||
std::unique_lock<std::mutex> l(device_lock);
|
||||
device_count = 0;
|
||||
device_data.clear();
|
||||
//gamepad counters
|
||||
int xbox_counter = 0;
|
||||
int ds4_counter = 0;
|
||||
int ds5_counter = 0;
|
||||
int switch_counter = 0;
|
||||
int bitdo_counter = 0;
|
||||
int shield_counter = 0;
|
||||
|
||||
for (auto &path : list ) {
|
||||
//Set devices paths
|
||||
std::string capacity = path + "/capacity";
|
||||
std::string capacity_level = path + "/capacity_level";
|
||||
std::string status = path + "/status";
|
||||
std::string model = path + "/model_name";
|
||||
std::ifstream input_capacity(capacity);
|
||||
std::ifstream input_capacity_level(capacity_level);
|
||||
std::ifstream input_status(status);
|
||||
std::ifstream device_name(model);
|
||||
std::string line;
|
||||
|
||||
device_data.push_back(device_batt());
|
||||
|
||||
// GAMEPADS
|
||||
//Xone and xpadneo devices
|
||||
if (check_gamepad == true) {
|
||||
if (path.find("gip") != std::string::npos || path.find("xpadneo") != std::string::npos) {
|
||||
if (xbox_count == 1 )
|
||||
device_data[device_count].name = "XBOX PAD";
|
||||
else
|
||||
device_data[device_count].name = "XBOX PAD-" + to_string(xbox_counter + 1);
|
||||
xbox_counter++;
|
||||
}
|
||||
//DualShock 4 devices
|
||||
if (path.find("sony_controller") != std::string::npos) {
|
||||
if (ds4_count == 1)
|
||||
device_data[device_count].name = "DS4 PAD";
|
||||
else
|
||||
device_data[device_count].name = "DS4 PAD-" + to_string(ds4_counter + 1);
|
||||
ds4_counter++;
|
||||
}
|
||||
//DualSense 5 devices
|
||||
//Dual Shock 4 added to hid-playstation in Linux 6.2
|
||||
if (path.find("ps-controller") != std::string::npos) {
|
||||
if (ds5_count == 1)
|
||||
device_data[device_count].name = "DS4/5 PAD";
|
||||
else
|
||||
device_data[device_count].name = "DS4/5 PAD-" + to_string(ds5_counter + 1);
|
||||
ds5_counter++;
|
||||
}
|
||||
//Nintendo Switch devices
|
||||
if (path.find("nintendo_switch_controller") != std::string::npos) {
|
||||
if (switch_count == 1)
|
||||
device_data[device_count].name = "SWITCH PAD";
|
||||
else
|
||||
device_data[device_count].name = "SWITCH PAD-" + to_string(switch_counter + 1);
|
||||
switch_counter++;
|
||||
}
|
||||
//8bitdo devices
|
||||
if (path.find("hid-e4") != std::string::npos) {
|
||||
if (bitdo_count == 1)
|
||||
device_data[device_count].name = "8BITDO PAD";
|
||||
else
|
||||
device_data[device_count].name = "8BITDO PAD-" + to_string(bitdo_counter + 1);
|
||||
bitdo_counter++;
|
||||
}
|
||||
//Shield devices
|
||||
if (path.find("thunderstrike") != std::string::npos) {
|
||||
if (shield_count == 1)
|
||||
device_data[device_count].name = "SHIELD PAD";
|
||||
else
|
||||
device_data[device_count].name = "SHIELD PAD-" + to_string(shield_counter + 1);
|
||||
shield_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
// MICE AND KEYBOARDS
|
||||
//Logitech Devices
|
||||
if (check_mouse == true) {
|
||||
if (path.find("hidpp_battery") != std::string::npos) {
|
||||
// Find a good way truncate name or retreive device type before using this
|
||||
// if (std::getline(device_name, line)) {
|
||||
// device_data[device_count].name = line;
|
||||
// }
|
||||
device_data[device_count].name = "LOGI MOUSE/KB";
|
||||
}
|
||||
}
|
||||
|
||||
//Get device charging status
|
||||
if (std::getline(input_status, line)) {
|
||||
if (line == "Charging" || line == "Full")
|
||||
device_data[device_count].is_charging = true;
|
||||
}
|
||||
//Get device Battery
|
||||
if (fs::exists(capacity)) {
|
||||
if (std::getline(input_capacity, line)) {
|
||||
device_data[device_count].battery_percent = line;
|
||||
device_data[device_count].report_percent = true;
|
||||
switch(std::stoi(line)) {
|
||||
case 0 ... 25:
|
||||
device_data[device_count].battery = "Low";
|
||||
break;
|
||||
case 26 ... 49:
|
||||
device_data[device_count].battery = "Normal";
|
||||
break;
|
||||
case 50 ... 74:
|
||||
device_data[device_count].battery = "High";
|
||||
break;
|
||||
case 75 ... 100:
|
||||
device_data[device_count].battery = "Full";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (std::getline(input_capacity_level, line)) {
|
||||
device_data[device_count].battery = line;
|
||||
}
|
||||
}
|
||||
std::sort(device_data.begin(), device_data.end());
|
||||
device_count += 1;
|
||||
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef MANGOHUD_DEVICE_H
|
||||
#define MANGOHUD_DEVICE_H
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "overlay_params.h"
|
||||
struct overlay_params;
|
||||
struct device_batt {
|
||||
std::string battery;
|
||||
std::string name;
|
||||
bool report_percent;
|
||||
std::string battery_percent;
|
||||
bool is_charging;
|
||||
};
|
||||
|
||||
extern std::vector<device_batt> device_data;
|
||||
extern std::mutex device_lock;
|
||||
|
||||
extern bool device_found;
|
||||
extern int device_count;
|
||||
void device_update(const overlay_params& params);
|
||||
void device_info();
|
||||
|
||||
|
||||
#endif // MANGOHUD_DEVICE_H
|
@ -1,165 +0,0 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <mesa/util/os_time.h>
|
||||
#include <numeric>
|
||||
#include <mutex>
|
||||
#include <algorithm>
|
||||
#include <condition_variable>
|
||||
#include <stdexcept>
|
||||
#include <iomanip>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
struct metric_t {
|
||||
std::string name;
|
||||
float value;
|
||||
std::string display_name;
|
||||
};
|
||||
|
||||
class fpsMetrics {
|
||||
private:
|
||||
std::vector<std::pair<uint64_t, float>> fps_stats;
|
||||
std::thread thread;
|
||||
std::mutex mtx;
|
||||
std::condition_variable cv;
|
||||
bool run = false;
|
||||
bool thread_init = false;
|
||||
bool terminate = false;
|
||||
bool resetting = false;
|
||||
|
||||
void calculate(){
|
||||
thread_init = true;
|
||||
while (true){
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
cv.wait(lock, [this] { return run; });
|
||||
|
||||
if (terminate)
|
||||
break;
|
||||
|
||||
std::vector<float> sorted_values;
|
||||
for (const auto& p : fps_stats)
|
||||
sorted_values.push_back(p.second);
|
||||
|
||||
std::sort(sorted_values.begin(), sorted_values.end());
|
||||
|
||||
auto it = metrics.begin();
|
||||
while (it != metrics.end()) {
|
||||
if (it->name == "AVG") {
|
||||
it->display_name = it->name;
|
||||
if (!fps_stats.empty()) {
|
||||
float sum = std::accumulate(fps_stats.begin(), fps_stats.end(), 0.0f,
|
||||
[](float acc, const std::pair<uint64_t, float>& p) {
|
||||
return acc + p.second;
|
||||
});
|
||||
it->value = sum / fps_stats.size();
|
||||
++it;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
float val = std::stof(it->name);
|
||||
if (val <= 0 || val >= 1 ) {
|
||||
SPDLOG_DEBUG("Failed to use fps metric, it's out of range {}", it->name);
|
||||
it = metrics.erase(it);
|
||||
break;
|
||||
}
|
||||
float multiplied_val = val * 100;
|
||||
std::ostringstream stream;
|
||||
if (multiplied_val == static_cast<int>(multiplied_val)) {
|
||||
stream << std::fixed << std::setprecision(0) << multiplied_val << "%";
|
||||
} else {
|
||||
stream << std::fixed << std::setprecision(1) << multiplied_val << "%";
|
||||
}
|
||||
it->display_name = stream.str();
|
||||
uint64_t idx = val * sorted_values.size() - 1;
|
||||
if (idx >= sorted_values.size())
|
||||
break;
|
||||
|
||||
it->value = sorted_values[idx];
|
||||
++it;
|
||||
} catch (const std::invalid_argument& e) {
|
||||
SPDLOG_DEBUG("Failed to use fps metric value {}", it->name);
|
||||
it = metrics.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
std::vector<metric_t> metrics;
|
||||
|
||||
fpsMetrics(std::vector<std::string> values){
|
||||
// capitalize string
|
||||
for (auto& val : values){
|
||||
for(char& c : val) {
|
||||
c = std::toupper(static_cast<unsigned char>(c));
|
||||
}
|
||||
|
||||
metrics.push_back({val, 0.0f});
|
||||
}
|
||||
|
||||
if (!thread_init){
|
||||
thread = std::thread(&fpsMetrics::calculate, this);
|
||||
}
|
||||
};
|
||||
|
||||
void update(uint64_t now, double fps){
|
||||
if (resetting)
|
||||
return;
|
||||
|
||||
if (fps > 0.0001)
|
||||
fps_stats.push_back({now, fps});
|
||||
|
||||
uint64_t ten_minute_duration = 600000000000ULL; // 10 minutes in nanoseconds
|
||||
|
||||
// Check if the system's uptime is less than 10 minutes
|
||||
if (now >= ten_minute_duration) {
|
||||
uint64_t ten_minutes_ago = now - ten_minute_duration;
|
||||
|
||||
fps_stats.erase(
|
||||
std::remove_if(
|
||||
fps_stats.begin(),
|
||||
fps_stats.end(),
|
||||
[ten_minutes_ago](const std::pair<uint64_t, float>& entry) {
|
||||
return entry.first < ten_minutes_ago;
|
||||
}
|
||||
),
|
||||
fps_stats.end()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void update_thread(){
|
||||
if (resetting)
|
||||
return;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
run = true;
|
||||
}
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
void reset_metrics(){
|
||||
resetting = true;
|
||||
while (run){}
|
||||
fps_stats.clear();
|
||||
resetting = false;
|
||||
}
|
||||
|
||||
~fpsMetrics(){
|
||||
terminate = true;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
run = true;
|
||||
}
|
||||
cv.notify_one();
|
||||
thread.join();
|
||||
}
|
||||
};
|
||||
|
||||
extern std::unique_ptr<fpsMetrics> fpsmetrics;
|
@ -0,0 +1,186 @@
|
||||
#include "gamepad.h"
|
||||
#include <filesystem.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace fs = ghc::filesystem;
|
||||
using namespace std;
|
||||
std::vector<gamepad> gamepad_data;
|
||||
std::vector<std::string> list;
|
||||
bool gamepad_found = false;
|
||||
int gamepad_count = 0;
|
||||
int xbox_count = 0;
|
||||
int ds4_count = 0;
|
||||
int ds5_count = 0;
|
||||
int switch_count = 0;
|
||||
int bitdo_count = 0;
|
||||
int logi_count = 0; //Logitech devices, mice & keyboards etc.
|
||||
|
||||
std::string xbox_paths [2]{"gip","xpadneo"};
|
||||
|
||||
static bool operator<(const gamepad& a, const gamepad& b)
|
||||
{
|
||||
return a.name < b.name;
|
||||
}
|
||||
|
||||
|
||||
void gamepad_update(){
|
||||
fs::path path("/sys/class/power_supply");
|
||||
list.clear();
|
||||
xbox_count = 0;
|
||||
ds4_count = 0;
|
||||
ds5_count = 0;
|
||||
switch_count = 0;
|
||||
bitdo_count = 0;
|
||||
for (auto &p : fs::directory_iterator(path)) {
|
||||
string fileName = p.path().filename();
|
||||
//Gamepads
|
||||
//CHECK XONE AND XPADNEO DEVICES
|
||||
for (string n : xbox_paths ) {
|
||||
if (fileName.find(n) != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
gamepad_found = true;
|
||||
xbox_count += 1;
|
||||
}
|
||||
}
|
||||
//CHECK FOR DUAL SHOCK 4 DEVICES
|
||||
if (fileName.find("sony_controller") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
gamepad_found = true;
|
||||
ds4_count +=1 ;
|
||||
}
|
||||
if (fileName.find("ps-controller") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
gamepad_found = true;
|
||||
ds5_count +=1 ;
|
||||
}
|
||||
//CHECK FOR NINTENDO SWITCH DEVICES
|
||||
if (fileName.find("nintendo_switch_controller") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
gamepad_found = true;
|
||||
switch_count += 1;
|
||||
}
|
||||
//CHECK * BITDO DEVICES
|
||||
if (fileName.find("hid-e4") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
gamepad_found = true;
|
||||
bitdo_count += 1;
|
||||
}
|
||||
// Mice and Keyboards
|
||||
//CHECK LOGITECH DEVICES
|
||||
if (fileName.find("hidpp_battery") != std::string::npos) {
|
||||
list.push_back(p.path());
|
||||
gamepad_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void gamepad_info () {
|
||||
gamepad_count = 0;
|
||||
gamepad_data.clear();
|
||||
//gamepad counters
|
||||
int xbox_counter = 0;
|
||||
int ds4_counter = 0;
|
||||
int ds5_counter = 0;
|
||||
int switch_counter = 0;
|
||||
int bitdo_counter = 0;
|
||||
|
||||
for (auto &path : list ) {
|
||||
//Set devices paths
|
||||
std::string capacity = path + "/capacity";
|
||||
std::string capacity_level = path + "/capacity_level";
|
||||
std::string status = path + "/status";
|
||||
std::string model = path + "/model_name";
|
||||
std::ifstream input_capacity(capacity);
|
||||
std::ifstream input_capacity_level(capacity_level);
|
||||
std::ifstream input_status(status);
|
||||
std::ifstream device_name(model);
|
||||
std::string line;
|
||||
|
||||
gamepad_data.push_back(gamepad());
|
||||
|
||||
//Xone and xpadneo devices
|
||||
if (path.find("gip") != std::string::npos || path.find("xpadneo") != std::string::npos) {
|
||||
if (xbox_count == 1 )
|
||||
gamepad_data[gamepad_count].name = "XBOX PAD";
|
||||
else
|
||||
gamepad_data[gamepad_count].name = "XBOX PAD-" + to_string(xbox_counter + 1);
|
||||
xbox_counter++;
|
||||
}
|
||||
//DualShock 4 devices
|
||||
if (path.find("sony_controller") != std::string::npos) {
|
||||
if (ds4_count == 1)
|
||||
gamepad_data[gamepad_count].name = "DS4 PAD";
|
||||
else
|
||||
gamepad_data[gamepad_count].name = "DS4 PAD-" + to_string(ds4_counter + 1);
|
||||
ds4_counter++;
|
||||
}
|
||||
//DualSense 5 devices
|
||||
//Dual Shock 4 added to hid-playstation in Linux 6.2
|
||||
if (path.find("ps-controller") != std::string::npos) {
|
||||
if (ds5_count == 1)
|
||||
gamepad_data[gamepad_count].name = "DS4/5 PAD";
|
||||
else
|
||||
gamepad_data[gamepad_count].name = "DS4/5 PAD-" + to_string(ds5_counter + 1);
|
||||
ds5_counter++;
|
||||
}
|
||||
//Nintendo Switch devices
|
||||
if (path.find("nintendo_switch_controller") != std::string::npos) {
|
||||
if (switch_count == 1)
|
||||
gamepad_data[gamepad_count].name = "SWITCH PAD";
|
||||
else
|
||||
gamepad_data[gamepad_count].name = "SWITCH PAD-" + to_string(switch_counter + 1);
|
||||
switch_counter++;
|
||||
}
|
||||
//8bitdo devices
|
||||
if (path.find("hid-e4") != std::string::npos) {
|
||||
if (bitdo_count == 1)
|
||||
gamepad_data[gamepad_count].name = "8BITDO PAD";
|
||||
else
|
||||
gamepad_data[gamepad_count].name = "8BITDO PAD-" + to_string(bitdo_counter + 1);
|
||||
bitdo_counter++;
|
||||
}
|
||||
//Logitech Devices
|
||||
if (path.find("hidpp_battery") != std::string::npos) {
|
||||
if (std::getline(device_name, line)) {
|
||||
gamepad_data[gamepad_count].name = line;
|
||||
}
|
||||
}
|
||||
//Get device charging status
|
||||
if (std::getline(input_status, line)) {
|
||||
if (line == "Charging" || line == "Full")
|
||||
gamepad_data[gamepad_count].is_charging = true;
|
||||
}
|
||||
//Get device Battery
|
||||
if (fs::exists(capacity)) {
|
||||
if (std::getline(input_capacity, line)) {
|
||||
gamepad_data[gamepad_count].battery_percent = line;
|
||||
gamepad_data[gamepad_count].report_percent = true;
|
||||
switch(std::stoi(line)) {
|
||||
case 0 ... 25:
|
||||
gamepad_data[gamepad_count].battery = "Low";
|
||||
break;
|
||||
case 26 ... 49:
|
||||
gamepad_data[gamepad_count].battery = "Normal";
|
||||
break;
|
||||
case 50 ... 74:
|
||||
gamepad_data[gamepad_count].battery = "High";
|
||||
break;
|
||||
case 75 ... 100:
|
||||
gamepad_data[gamepad_count].battery = "Full";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (std::getline(input_capacity_level, line)) {
|
||||
gamepad_data[gamepad_count].battery = line;
|
||||
}
|
||||
}
|
||||
std::sort(gamepad_data.begin(), gamepad_data.end());
|
||||
gamepad_count += 1;
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#ifndef MANGOHUD_GAMEPAD_H
|
||||
#define MANGOHUD_GAMEPAD_H
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct gamepad {
|
||||
std::string battery;
|
||||
std::string name;
|
||||
bool report_percent;
|
||||
std::string battery_percent;
|
||||
bool is_charging;
|
||||
};
|
||||
|
||||
extern std::vector<gamepad> gamepad_data;
|
||||
|
||||
extern bool gamepad_found;
|
||||
extern int gamepad_count;
|
||||
void gamepad_update();
|
||||
void gamepad_info();
|
||||
|
||||
|
||||
#endif // MANGOHUD_GAMEPAD_H
|
@ -1,51 +0,0 @@
|
||||
#include <sys/stat.h>
|
||||
#include <thread>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <filesystem.h>
|
||||
#include <inttypes.h>
|
||||
#include <mesa/util/os_time.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include "gpu.h"
|
||||
#include "hud_elements.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
namespace fs = ghc::filesystem;
|
||||
|
||||
class Intel {
|
||||
private:
|
||||
bool init = false;
|
||||
bool runtime = false;
|
||||
bool stop = false;
|
||||
struct gpuInfo gpu_info_intel {};
|
||||
FILE* fdinfo;
|
||||
struct stat stat_buffer;
|
||||
std::thread thread;
|
||||
|
||||
FILE* find_fd();
|
||||
void intel_gpu_thread();
|
||||
uint64_t get_gpu_time();
|
||||
void get_fdinfo();
|
||||
|
||||
public:
|
||||
Intel() {
|
||||
if (stat("/run/pressure-vessel", &stat_buffer) == 0)
|
||||
runtime = true;
|
||||
|
||||
fdinfo = find_fd();
|
||||
// thread = std::thread(&Intel::intel_gpu_thread, this);
|
||||
}
|
||||
|
||||
void update() {
|
||||
if (fdinfo)
|
||||
get_fdinfo();
|
||||
|
||||
gpu_info = gpu_info_intel;
|
||||
}
|
||||
|
||||
// ~Intel(){
|
||||
// stop = true;
|
||||
// thread.join();
|
||||
// }
|
||||
};
|
||||
|
||||
extern std::unique_ptr<Intel> intel;
|
@ -1,79 +0,0 @@
|
||||
#include <filesystem.h>
|
||||
#include <mesa/util/os_time.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "msm.h"
|
||||
std::unique_ptr<MSM> msm;
|
||||
namespace fs = ghc::filesystem;
|
||||
|
||||
uint64_t MSM::get_gpu_time() {
|
||||
char line[256];
|
||||
uint64_t total_val = 0;
|
||||
for (auto fd : fdinfo) {
|
||||
rewind(fd);
|
||||
fflush(fd);
|
||||
uint64_t val = 0;
|
||||
while (fgets(line, sizeof(line), fd)){
|
||||
if (sscanf(line, "drm-engine-gpu: %" SCNu64 " ns", &val) == 1) {
|
||||
total_val += val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return total_val;
|
||||
}
|
||||
|
||||
void MSM::find_fd() {
|
||||
DIR* dir = opendir("/proc/self/fdinfo");
|
||||
if (!dir) {
|
||||
perror("Failed to open directory");
|
||||
}
|
||||
|
||||
for (const auto& entry : fs::directory_iterator("/proc/self/fdinfo")){
|
||||
FILE* file = fopen(entry.path().string().c_str(), "r");
|
||||
|
||||
if (!file) continue;
|
||||
|
||||
char line[256];
|
||||
bool found_driver = false;
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
if (strstr(line, "msm") != NULL)
|
||||
found_driver = true;
|
||||
|
||||
if (found_driver) {
|
||||
if(strstr(line, "drm-engine-gpu")) {
|
||||
fdinfo.push_back(file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_driver)
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
void MSM::get_fdinfo() {
|
||||
static uint64_t previous_gpu_time, previous_time, now, gpu_time_now;
|
||||
gpu_time_now = get_gpu_time();
|
||||
now = os_time_get_nano();
|
||||
|
||||
if (previous_time && previous_gpu_time && gpu_time_now > previous_gpu_time){
|
||||
float time_since_last = now - previous_time;
|
||||
float gpu_since_last = gpu_time_now - previous_gpu_time;
|
||||
auto result = int((gpu_since_last / time_since_last) * 100);
|
||||
if (result > 100)
|
||||
result = 100;
|
||||
|
||||
gpu_info_msm.load = result;
|
||||
previous_gpu_time = gpu_time_now;
|
||||
previous_time = now;
|
||||
} else {
|
||||
previous_gpu_time = gpu_time_now;
|
||||
previous_time = now;
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "gpu.h"
|
||||
|
||||
class MSM {
|
||||
private:
|
||||
struct gpuInfo gpu_info_msm {};
|
||||
std::vector<FILE*> fdinfo;
|
||||
void find_fd();
|
||||
uint64_t get_gpu_time();
|
||||
void get_fdinfo();
|
||||
|
||||
public:
|
||||
MSM() {
|
||||
find_fd();
|
||||
}
|
||||
|
||||
~MSM() {
|
||||
for (size_t i = 0; i < fdinfo.size(); i++) {
|
||||
fclose(fdinfo[i]);
|
||||
}
|
||||
fdinfo.clear();
|
||||
}
|
||||
|
||||
void update() {
|
||||
if (!fdinfo.empty())
|
||||
get_fdinfo();
|
||||
|
||||
gpu_info = gpu_info_msm;
|
||||
}
|
||||
};
|
||||
|
||||
extern std::unique_ptr<MSM> msm;
|
@ -1,58 +0,0 @@
|
||||
#include "net.h"
|
||||
#include "hud_elements.h"
|
||||
|
||||
Net::Net() {
|
||||
should_reset = false;
|
||||
fs::path net_dir(NETDIR);
|
||||
if (fs::exists(net_dir) && fs::is_directory(net_dir)) {
|
||||
for (const auto& entry : fs::directory_iterator(net_dir)) {
|
||||
if (fs::is_directory(entry.status())) {
|
||||
auto val = entry.path().filename().string();
|
||||
if (val == "lo")
|
||||
continue;
|
||||
|
||||
if (!HUDElements.params->network.empty() && HUDElements.params->network.front() == "1") {
|
||||
interfaces.push_back({entry.path().filename().string(), 0, 0});
|
||||
} else if (!HUDElements.params->network.empty()){
|
||||
auto it = std::find(HUDElements.params->network.begin(), HUDElements.params->network.end(), val);
|
||||
if (it != HUDElements.params->network.end())
|
||||
interfaces.push_back({entry.path().filename().string(), 0, 0});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (interfaces.empty())
|
||||
SPDLOG_ERROR("Network: couldn't find any interfaces");
|
||||
}
|
||||
|
||||
void Net::update() {
|
||||
if (!interfaces.empty()) {
|
||||
for (auto& iface : interfaces) {
|
||||
// path to tx_bytes and rx_bytes
|
||||
std::string txfile = (NETDIR + iface.name + TXFILE);
|
||||
std::string rxfile = (NETDIR + iface.name + RXFILE);
|
||||
|
||||
// amount of bytes at previous update
|
||||
uint64_t prevTx = iface.txBytes;
|
||||
uint64_t prevRx = iface.rxBytes;
|
||||
|
||||
// current amount of bytes
|
||||
iface.txBytes = std::stoll(read_line(txfile));
|
||||
iface.rxBytes = std::stoll(read_line(rxfile));
|
||||
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
// calculate the bytes per second since last update
|
||||
iface.txBps = calculateThroughput(iface.txBytes, prevTx, iface.previousTime, now);
|
||||
iface.rxBps = calculateThroughput(iface.rxBytes, prevRx, iface.previousTime, now);
|
||||
iface.previousTime = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t Net::calculateThroughput(long long currentBytes, long long previousBytes,
|
||||
std::chrono::steady_clock::time_point previousTime,
|
||||
std::chrono::steady_clock::time_point currentTime) {
|
||||
std::chrono::duration<double> elapsed = (currentTime - previousTime);
|
||||
return static_cast<long long>((currentBytes - previousBytes) / elapsed.count());
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include "filesystem.h"
|
||||
#include "file_utils.h"
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace fs = ghc::filesystem;
|
||||
|
||||
#ifndef NETDIR
|
||||
#define NETDIR "/sys/class/net/"
|
||||
#endif
|
||||
|
||||
#ifndef TXFILE
|
||||
#define TXFILE "/statistics/tx_bytes"
|
||||
#endif
|
||||
|
||||
#ifndef RXFILE
|
||||
#define RXFILE "/statistics/rx_bytes"
|
||||
#endif
|
||||
|
||||
class Net {
|
||||
public:
|
||||
bool should_reset = false;
|
||||
struct networkInterface {
|
||||
std::string name;
|
||||
uint64_t txBytes;
|
||||
uint64_t rxBytes;
|
||||
uint64_t txBps;
|
||||
uint64_t rxBps;
|
||||
std::chrono::steady_clock::time_point previousTime;
|
||||
};
|
||||
|
||||
Net();
|
||||
void update();
|
||||
std::vector<networkInterface> interfaces = {};
|
||||
|
||||
private:
|
||||
uint64_t calculateThroughput(long long currentBytes, long long previousBytes,
|
||||
std::chrono::steady_clock::time_point previousTime,
|
||||
std::chrono::steady_clock::time_point currentTime);
|
||||
};
|
||||
|
||||
extern std::unique_ptr<Net> net;
|
@ -1,92 +0,0 @@
|
||||
#include "shell.h"
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
#include <sys/wait.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include "string_utils.h"
|
||||
#include <array>
|
||||
|
||||
std::string Shell::readOutput() {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
|
||||
std::array<char, 128> buffer;
|
||||
std::string result;
|
||||
ssize_t count;
|
||||
while ((count = ::read(from_shell[0], buffer.data(), buffer.size())) > 0) {
|
||||
result.append(buffer.data(), count);
|
||||
}
|
||||
|
||||
// Split the result into lines and return the last line
|
||||
std::istringstream stream(result);
|
||||
std::string line;
|
||||
std::string last_line;
|
||||
while (std::getline(stream, line)) {
|
||||
last_line = line;
|
||||
}
|
||||
|
||||
SPDLOG_DEBUG("Shell: recieved output: {}", last_line);
|
||||
return last_line;
|
||||
}
|
||||
|
||||
Shell::Shell() {
|
||||
static bool failed;
|
||||
if (pipe(to_shell) == -1) {
|
||||
SPDLOG_ERROR("Failed to create to_shell pipe: {}", strerror(errno));
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if (pipe(from_shell) == -1) {
|
||||
SPDLOG_ERROR("Failed to create from_shell pipe: {}", strerror(errno));
|
||||
failed = true;
|
||||
}
|
||||
|
||||
// if either pipe fails, there's no point in continuing.
|
||||
if (failed){
|
||||
SPDLOG_ERROR("Shell has failed, will not be able to use exec");
|
||||
return;
|
||||
}
|
||||
|
||||
shell_pid = fork();
|
||||
|
||||
if (shell_pid == 0) { // Child process
|
||||
close(to_shell[1]);
|
||||
close(from_shell[0]);
|
||||
|
||||
dup2(to_shell[0], STDIN_FILENO);
|
||||
dup2(from_shell[1], STDOUT_FILENO);
|
||||
dup2(from_shell[1], STDERR_FILENO);
|
||||
execl("/bin/sh", "sh", nullptr);
|
||||
exit(1); // Exit if execl fails
|
||||
} else {
|
||||
close(to_shell[0]);
|
||||
close(from_shell[1]);
|
||||
|
||||
// Set the read end of the from_shell pipe to non-blocking
|
||||
setNonBlocking(from_shell[0]);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
|
||||
std::string Shell::exec(std::string cmd) {
|
||||
if (!success)
|
||||
return "";
|
||||
|
||||
writeCommand(cmd);
|
||||
return readOutput();
|
||||
}
|
||||
|
||||
void Shell::writeCommand(std::string command) {
|
||||
if (write(to_shell[1], command.c_str(), command.length()) == -1)
|
||||
SPDLOG_ERROR("Failed to write to shell");
|
||||
|
||||
trim(command);
|
||||
SPDLOG_DEBUG("Shell: wrote command: {}", command);
|
||||
}
|
||||
|
||||
Shell::~Shell() {
|
||||
if (write(to_shell[1], "exit\n", 5) == -1)
|
||||
SPDLOG_ERROR("Failed exit shell");
|
||||
close(to_shell[1]);
|
||||
close(from_shell[0]);
|
||||
waitpid(shell_pid, nullptr, 0);
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
#pragma once
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#ifdef __linux__
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
class Shell {
|
||||
private:
|
||||
int to_shell[2];
|
||||
int from_shell[2];
|
||||
pid_t shell_pid;
|
||||
bool success;
|
||||
|
||||
#ifdef __linux__
|
||||
void setNonBlocking(int fd) {
|
||||
int flags = fcntl(fd, F_GETFL, 0);
|
||||
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
#endif
|
||||
|
||||
void writeCommand(std::string command);
|
||||
std::string readOutput();
|
||||
|
||||
public:
|
||||
Shell();
|
||||
~Shell();
|
||||
std::string exec(std::string cmd);
|
||||
|
||||
};
|
||||
|
||||
extern std::unique_ptr<Shell> shell;
|
@ -1,63 +0,0 @@
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <dlfcn.h>
|
||||
#include <cstdio>
|
||||
#include "real_dlsym.h"
|
||||
#include "wayland_hook.h"
|
||||
|
||||
EXPORT_C_(struct wl_display*) wl_display_connect(const char *name);
|
||||
EXPORT_C_(struct wl_display*) wl_display_connect_to_fd(int fd);
|
||||
|
||||
typedef struct wl_display* (*pwl_display_connect)(const char *name);
|
||||
typedef struct wl_display* (*pwl_display_connect_to_fd)(int fd);
|
||||
|
||||
pwl_display_connect wl_display_connect_ptr = nullptr;
|
||||
pwl_display_connect_to_fd wl_display_connect_to_fd_ptr = nullptr;
|
||||
void* wl_handle = nullptr;
|
||||
struct wl_display* wl_display_ptr = nullptr;
|
||||
|
||||
EXPORT_C_(struct wl_display*) wl_display_connect(const char *name)
|
||||
{
|
||||
struct wl_display *ret = nullptr;
|
||||
|
||||
if (!wl_handle) {
|
||||
wl_handle = real_dlopen("libwayland-client.so", RTLD_LAZY);
|
||||
}
|
||||
|
||||
if (wl_handle) {
|
||||
wl_display_connect_ptr = (pwl_display_connect)real_dlsym(wl_handle, "wl_display_connect");
|
||||
wl_display_connect_to_fd_ptr = (pwl_display_connect_to_fd)real_dlsym(wl_handle, "wl_display_connect_to_fd");
|
||||
|
||||
ret = wl_display_connect_ptr(name);
|
||||
|
||||
if (!wl_display_ptr) {
|
||||
wl_display_ptr = ret;
|
||||
init_wayland_data();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_C_(struct wl_display*) wl_display_connect_to_fd(int fd)
|
||||
{
|
||||
struct wl_display *ret = nullptr;
|
||||
|
||||
if (!wl_handle) {
|
||||
wl_handle = real_dlopen("libwayland-client.so", RTLD_LAZY);
|
||||
}
|
||||
|
||||
if (wl_handle) {
|
||||
wl_display_connect_to_fd_ptr = (pwl_display_connect_to_fd)real_dlsym(wl_handle, "wl_display_connect_to_fd");
|
||||
wl_display_connect_ptr = (pwl_display_connect)real_dlsym(wl_handle, "wl_display_connect");
|
||||
|
||||
ret = wl_display_connect_to_fd_ptr(fd);
|
||||
|
||||
if (!wl_display_ptr) {
|
||||
wl_display_ptr = ret;
|
||||
init_wayland_data();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#include <wayland-client.h>
|
||||
#include <vector>
|
||||
|
||||
#ifndef KeySym
|
||||
typedef unsigned long KeySym;
|
||||
#endif
|
||||
|
||||
extern void* wl_handle;
|
||||
extern struct wl_display* wl_display_ptr;
|
||||
extern std::vector<KeySym> wl_pressed_keys;
|
||||
|
||||
void init_wayland_data();
|
||||
void update_wl_queue();
|
@ -1,118 +0,0 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
#include <wayland-client.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <sys/mman.h>
|
||||
#include "wayland_hook.h"
|
||||
#include "timing.hpp"
|
||||
#include "keybinds.h"
|
||||
|
||||
struct wl_seat* seat = nullptr;
|
||||
struct wl_keyboard* keyboard = nullptr;
|
||||
struct xkb_context *context_xkb = nullptr;
|
||||
struct xkb_keymap *keymap_xkb = nullptr;
|
||||
struct xkb_state *state_xkb = nullptr;
|
||||
struct wl_event_queue* queue = nullptr;
|
||||
std::vector<KeySym> wl_pressed_keys {};
|
||||
|
||||
static void registry_handle_global(void *data, struct wl_registry* registry, uint32_t name, const char *interface, uint32_t version)
|
||||
{
|
||||
if(strcmp(interface, wl_seat_interface.name) == 0)
|
||||
{
|
||||
seat = (struct wl_seat*)wl_registry_bind(registry, name, &wl_seat_interface, 7);
|
||||
}
|
||||
}
|
||||
|
||||
static void registry_handle_global_remove(void *data, struct wl_registry *registry, uint32_t name){}
|
||||
|
||||
static void wl_keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size)
|
||||
{
|
||||
char* map_shm = (char*)mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
|
||||
if(!context_xkb)
|
||||
context_xkb = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
if(keymap_xkb && state_xkb)
|
||||
{
|
||||
xkb_keymap_unref(keymap_xkb);
|
||||
xkb_state_unref(state_xkb);
|
||||
}
|
||||
|
||||
keymap_xkb = xkb_keymap_new_from_string(
|
||||
context_xkb, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
state_xkb = xkb_state_new(keymap_xkb);
|
||||
|
||||
munmap((void*)map_shm, size);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void wl_keyboard_enter(void *user_data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys){}
|
||||
|
||||
static void wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface)
|
||||
{
|
||||
wl_pressed_keys.clear();
|
||||
}
|
||||
|
||||
static void wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
|
||||
{
|
||||
xkb_keycode_t keycode = key + 8;
|
||||
xkb_keysym_t keysym = xkb_state_key_get_one_sym(state_xkb, keycode);
|
||||
|
||||
if(state)
|
||||
{
|
||||
wl_pressed_keys.push_back(keysym);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto it = std::find(wl_pressed_keys.begin(), wl_pressed_keys.end(), keysym);
|
||||
if(it != wl_pressed_keys.end())
|
||||
wl_pressed_keys.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
static void wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group){}
|
||||
|
||||
static void wl_keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay){}
|
||||
|
||||
struct wl_registry_listener registry_listener {
|
||||
.global = registry_handle_global,
|
||||
.global_remove = registry_handle_global_remove
|
||||
};
|
||||
|
||||
struct wl_keyboard_listener keyboard_listener {
|
||||
.keymap = wl_keyboard_keymap,
|
||||
.enter = wl_keyboard_enter,
|
||||
.leave = wl_keyboard_leave,
|
||||
.key = wl_keyboard_key,
|
||||
.modifiers = wl_keyboard_modifiers,
|
||||
.repeat_info = wl_keyboard_repeat_info
|
||||
};
|
||||
|
||||
void update_wl_queue()
|
||||
{
|
||||
wl_display_roundtrip_queue(wl_display_ptr, queue);
|
||||
}
|
||||
|
||||
void init_wayland_data()
|
||||
{
|
||||
if (!wl_display_ptr)
|
||||
return;
|
||||
|
||||
struct wl_display *display_wrapped = (struct wl_display*)wl_proxy_create_wrapper(wl_display_ptr);
|
||||
queue = wl_display_create_queue(wl_display_ptr);
|
||||
wl_proxy_set_queue((struct wl_proxy*)display_wrapped, queue);
|
||||
wl_registry *registry = wl_display_get_registry(display_wrapped);
|
||||
wl_proxy_wrapper_destroy(display_wrapped);
|
||||
wl_registry_add_listener(registry, ®istry_listener, NULL);
|
||||
update_wl_queue();
|
||||
update_wl_queue();
|
||||
keyboard = wl_seat_get_keyboard(seat);
|
||||
wl_keyboard_add_listener(keyboard, &keyboard_listener, NULL);
|
||||
update_wl_queue();
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
#include "file_utils.h"
|
||||
#include <filesystem.h>
|
||||
#include <string>
|
||||
|
||||
namespace fs = ghc::filesystem;
|
||||
|
||||
class WineSync {
|
||||
private:
|
||||
enum syncMethods {
|
||||
NONE,
|
||||
WINESERVER,
|
||||
ESYNC,
|
||||
FSYNC,
|
||||
NTSYNC
|
||||
};
|
||||
|
||||
int method = 0;
|
||||
bool inside_wine = true;
|
||||
|
||||
const char* methods[5] = {
|
||||
"NONE",
|
||||
"Wserver",
|
||||
"Esync",
|
||||
"Fsync",
|
||||
"NTsync"
|
||||
};
|
||||
|
||||
public:
|
||||
WineSync() {
|
||||
#ifdef __linux__
|
||||
// check that's were inside wine
|
||||
std::string wineProcess = get_exe_path();
|
||||
auto n = wineProcess.find_last_of('/');
|
||||
std::string preloader = wineProcess.substr(n + 1);
|
||||
if (preloader != "wine-preloader" && preloader != "wine64-preloader"){
|
||||
inside_wine = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const char* paths[2] {
|
||||
"/proc/self/map_files",
|
||||
"/proc/self/fd"
|
||||
};
|
||||
|
||||
// check which sync wine is using, if any.
|
||||
fs::path path;
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
|
||||
path = paths[i];
|
||||
for (auto& p : fs::directory_iterator(path)) {
|
||||
auto filepath = p.path().string();
|
||||
const char* filename = filepath.c_str();
|
||||
auto sym = read_symlink(filename);
|
||||
if (sym.find("winesync") != std::string::npos)
|
||||
method = syncMethods::NTSYNC;
|
||||
else if (sym.find("fsync") != std::string::npos)
|
||||
method = syncMethods::FSYNC;
|
||||
else if (sym.find("ntsync") != std::string::npos)
|
||||
method = syncMethods::NTSYNC;
|
||||
else if (sym.find("esync") != std::string::npos)
|
||||
method = syncMethods::ESYNC;
|
||||
|
||||
if (method)
|
||||
break;
|
||||
|
||||
}
|
||||
if (method)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
bool valid() {
|
||||
return inside_wine;
|
||||
}
|
||||
|
||||
// return sync method as display name
|
||||
std::string get_method() {
|
||||
return methods[method];
|
||||
}
|
||||
};
|
||||
|
||||
extern std::unique_ptr<WineSync> winesync_ptr;
|
@ -1,13 +1,11 @@
|
||||
[wrap-file]
|
||||
directory = imgui-1.89.9
|
||||
source_url = https://github.com/ocornut/imgui/archive/refs/tags/v1.89.9.tar.gz
|
||||
source_filename = imgui-1.89.9.tar.gz
|
||||
source_hash = 1acc27a778b71d859878121a3f7b287cd81c29d720893d2b2bf74455bf9d52d6
|
||||
patch_filename = imgui_1.89.9-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/imgui_1.89.9-1/get_patch
|
||||
patch_hash = 9b21290c597d76bf8d4eeb3f9ffa024b11d9ea6c61e91d648ccc90b42843d584
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/imgui_1.89.9-1/imgui-1.89.9.tar.gz
|
||||
wrapdb_version = 1.89.9-1
|
||||
directory = imgui-1.81
|
||||
source_url = https://github.com/ocornut/imgui/archive/v1.81.tar.gz
|
||||
source_filename = imgui-1.81.tar.gz
|
||||
source_hash = f7c619e03a06c0f25e8f47262dbc32d61fd033d2c91796812bf0f8c94fca78fb
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/imgui_1.81-1/get_patch
|
||||
patch_filename = imgui-1.81-1-wrap.zip
|
||||
patch_hash = 6d00b442690b6a5c5d8f898311daafbce16d370cf64f53294c3b8c5c661e435f
|
||||
|
||||
[provide]
|
||||
imgui = imgui_dep
|
||||
|
@ -1,13 +0,0 @@
|
||||
[wrap-file]
|
||||
directory = implot-0.16
|
||||
source_url = https://github.com/epezent/implot/archive/refs/tags/v0.16.zip
|
||||
source_filename = implot-0.16.zip
|
||||
source_hash = 24f772c688f6b8a6e19d7efc10e4923a04a915f13d487b08b83553aa62ae1708
|
||||
patch_filename = implot_0.16-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/implot_0.16-1/get_patch
|
||||
patch_hash = 1c6b1462066a5452fa50c1da1dd47fed841f28232972c82d778f2962936568c7
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/implot_0.16-1/implot-0.16.zip
|
||||
wrapdb_version = 0.16-1
|
||||
|
||||
[provide]
|
||||
implot = implot_dep
|
@ -1,13 +1,12 @@
|
||||
[wrap-file]
|
||||
directory = spdlog-1.14.1
|
||||
source_url = https://github.com/gabime/spdlog/archive/refs/tags/v1.14.1.tar.gz
|
||||
source_filename = spdlog-1.14.1.tar.gz
|
||||
source_hash = 1586508029a7d0670dfcb2d97575dcdc242d3868a259742b69f100801ab4e16b
|
||||
patch_filename = spdlog_1.14.1-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/spdlog_1.14.1-1/get_patch
|
||||
patch_hash = ae878e732330ea1048f90d7e117c40c0cd2a6fb8ae5492c7955818ce3aaade6c
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/spdlog_1.14.1-1/spdlog-1.14.1.tar.gz
|
||||
wrapdb_version = 1.14.1-1
|
||||
directory = spdlog-1.8.5
|
||||
source_url = https://github.com/gabime/spdlog/archive/v1.8.5.tar.gz
|
||||
source_filename = v1.8.5.tar.gz
|
||||
source_hash = 944d0bd7c763ac721398dca2bb0f3b5ed16f67cef36810ede5061f35a543b4b8
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/spdlog_1.8.5-1/get_patch
|
||||
patch_filename = spdlog-1.8.5-1-wrap.zip
|
||||
patch_hash = 3c38f275d5792b1286391102594329e98b17737924b344f98312ab09929b74be
|
||||
|
||||
[provide]
|
||||
spdlog = spdlog_dep
|
||||
|
||||
|
Loading…
Reference in New Issue