From a5a2ec4f7a855ad35bde6362796a0a07fd419cf7 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 27 Oct 2019 07:25:43 +0100 Subject: proto/wine: add support for proton --- proto-wine/ftnoir_protocol_wine.cpp | 14 ++- proto-wine/ftnoir_protocol_wine.h | 13 ++ proto-wine/ftnoir_protocol_wine_dialog.cpp | 26 +++- proto-wine/ftnoir_winecontrols.ui | 195 +++++++++-------------------- proto-wine/lang/nl_NL.ts | 8 +- proto-wine/lang/ru_RU.ts | 8 +- proto-wine/lang/stub.ts | 8 +- proto-wine/lang/zh_CN.ts | 8 +- proto-wine/proton.cpp | 96 ++++++++++++++ 9 files changed, 221 insertions(+), 155 deletions(-) create mode 100644 proto-wine/proton.cpp (limited to 'proto-wine') diff --git a/proto-wine/ftnoir_protocol_wine.cpp b/proto-wine/ftnoir_protocol_wine.cpp index 2e618ff9..ce6f6229 100644 --- a/proto-wine/ftnoir_protocol_wine.cpp +++ b/proto-wine/ftnoir_protocol_wine.cpp @@ -51,12 +51,24 @@ void wine::pose(const double *headpose, const double*) } } +QProcessEnvironment make_steam_environ(const QString& proton_version); +QString proton_path(const QString& proton_version); + module_status wine::initialize() { #ifndef OTR_WINE_NO_WRAPPER static const QString library_path(OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH); + + QString wine_path = "wine"; + auto env = QProcessEnvironment::systemEnvironment(); + if (s.variant_proton) + { + env = make_steam_environ(s.proton_version); + wine_path = proton_path(s.proton_version); + } + wrapper.setWorkingDirectory(OPENTRACK_BASE_PATH); - wrapper.start("wine", { library_path + "opentrack-wrapper-wine.exe.so" }); + wrapper.start(wine_path, { library_path + "opentrack-wrapper-wine.exe.so" }); #endif if (lck_shm.success()) diff --git a/proto-wine/ftnoir_protocol_wine.h b/proto-wine/ftnoir_protocol_wine.h index ed142f83..3c64df68 100644 --- a/proto-wine/ftnoir_protocol_wine.h +++ b/proto-wine/ftnoir_protocol_wine.h @@ -6,12 +6,23 @@ #include "ui_ftnoir_winecontrols.h" +#include "options/options.hpp" +using namespace options; + #include #include #include #include +struct settings : opts +{ + settings() : opts{"proto-wine"} {} + value variant_proton{b, "variant-proton", false }, + variant_wine{b, "variant-wine", true }; + value proton_version{b, "proton-version", {} }; +}; + class wine : TR, public IProtocol { Q_OBJECT @@ -35,6 +46,7 @@ public: private: shm_wrapper lck_shm { WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM) }; WineSHM* shm = nullptr; + settings s; #ifndef OTR_WINE_NO_WRAPPER QProcess wrapper; @@ -55,6 +67,7 @@ public: private: Ui::UICFTControls ui; + settings s; private slots: void doOK(); diff --git a/proto-wine/ftnoir_protocol_wine_dialog.cpp b/proto-wine/ftnoir_protocol_wine_dialog.cpp index a388df70..bf431c66 100644 --- a/proto-wine/ftnoir_protocol_wine_dialog.cpp +++ b/proto-wine/ftnoir_protocol_wine_dialog.cpp @@ -2,18 +2,34 @@ #include #include "api/plugin-api.hpp" +static const char* proton_versions[] = { + "4.11", "4.2", "3.16", "3.7", +}; + FTControls::FTControls() { - ui.setupUi( this ); - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + ui.setupUi(this); + + for (const char* version : proton_versions) + ui.proton_version->addItem(version, QVariant{version}); + + tie_setting(s.proton_version, ui.proton_version); + tie_setting(s.variant_wine, ui.variant_wine); + tie_setting(s.variant_proton, ui.variant_proton); + + connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &FTControls::doOK); + connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &FTControls::doCancel); } -void FTControls::doOK() { +void FTControls::doOK() +{ + s.b->save(); close(); } -void FTControls::doCancel() { +void FTControls::doCancel() +{ + s.b->reload(); close(); } diff --git a/proto-wine/ftnoir_winecontrols.ui b/proto-wine/ftnoir_winecontrols.ui index 9356c448..79fca47d 100644 --- a/proto-wine/ftnoir_winecontrols.ui +++ b/proto-wine/ftnoir_winecontrols.ui @@ -9,16 +9,16 @@ 0 0 - 409 - 110 + 332 + 204 - FreeTrack settings FaceTrackNoIR + Wine settings - - images/freetrack.pngimages/freetrack.png + + :/images/wine.png:/images/wine.png Qt::LeftToRight @@ -26,141 +26,70 @@ false - + - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - + + + Wine variant - + + + + + + 0 + 0 + + + + Wine (system) + + + + + + + + 0 + 0 + + + + Proton (Steam) + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + + - - - - - There are no settings necessary for the Wine protocol. - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QLayout::SetDefaultConstraint - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - OK - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - Cancel - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 10 - 20 - - - - - + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + - + + + startEngineClicked() diff --git a/proto-wine/lang/nl_NL.ts b/proto-wine/lang/nl_NL.ts index 239e73d1..41f368c6 100644 --- a/proto-wine/lang/nl_NL.ts +++ b/proto-wine/lang/nl_NL.ts @@ -4,19 +4,19 @@ UICFTControls - FreeTrack settings FaceTrackNoIR + Wine settings - There are no settings necessary for the Wine protocol. + Wine variant - OK + Wine (system) - Cancel + Proton (Steam) diff --git a/proto-wine/lang/ru_RU.ts b/proto-wine/lang/ru_RU.ts index 1e80e43f..d6a10fac 100644 --- a/proto-wine/lang/ru_RU.ts +++ b/proto-wine/lang/ru_RU.ts @@ -4,19 +4,19 @@ UICFTControls - FreeTrack settings FaceTrackNoIR + Wine settings - There are no settings necessary for the Wine protocol. + Wine variant - OK + Wine (system) - Cancel + Proton (Steam) diff --git a/proto-wine/lang/stub.ts b/proto-wine/lang/stub.ts index 2da10a0b..2b4793e0 100644 --- a/proto-wine/lang/stub.ts +++ b/proto-wine/lang/stub.ts @@ -4,19 +4,19 @@ UICFTControls - FreeTrack settings FaceTrackNoIR + Wine settings - There are no settings necessary for the Wine protocol. + Wine variant - OK + Wine (system) - Cancel + Proton (Steam) diff --git a/proto-wine/lang/zh_CN.ts b/proto-wine/lang/zh_CN.ts index 2da10a0b..2b4793e0 100644 --- a/proto-wine/lang/zh_CN.ts +++ b/proto-wine/lang/zh_CN.ts @@ -4,19 +4,19 @@ UICFTControls - FreeTrack settings FaceTrackNoIR + Wine settings - There are no settings necessary for the Wine protocol. + Wine variant - OK + Wine (system) - Cancel + Proton (Steam) diff --git a/proto-wine/proton.cpp b/proto-wine/proton.cpp new file mode 100644 index 00000000..c36dbc86 --- /dev/null +++ b/proto-wine/proton.cpp @@ -0,0 +1,96 @@ +/* Copyright (c) 2019 Stanislaw Halik + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef OTR_WINE_NO_WRAPPER + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +static QString home_directory() +{ + struct passwd *pwptr = nullptr, pw{}; + uid_t uid = getuid(); + int shift = 16; + do { + auto buf = std::make_unique(1 << shift); + int error = getpwuid_r(uid, &pw, buf.get(), 1 << shift, &pwptr); + if (error) + { + if (errno != EDOM) + return {}; + else + continue; + } + else + break; + } while (++shift < 28); + + if (!pwptr) + return {}; + + return pwptr->pw_dir; +} + +QProcessEnvironment make_steam_environ(const QString& proton_version) +{ + auto ret = QProcessEnvironment::systemEnvironment(); + QString home = home_directory(); + + auto expand = [&](QString x) { + x.replace("HOME", home); + x.replace("PROTON", proton_version); + return x; + }; + + QString path = expand( + "HOME/.local/share/Steam/steamapps/common/Proton PROTON/dist/bin:" + "HOME/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/bin:" + "HOME/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/usr/bin" + ); + path += ':'; path += qgetenv("PATH"); + ret.insert("PATH", path); + + QString library_path = expand( + ":HOME/.local/share/Steam/steamapps/common/Proton PROTON/dist/lib" + ":HOME/.local/share/Steam/steamapps/common/Proton PROTON/dist/lib64" + ":HOME/.local/share/Steam/ubuntu12_32/steam-runtime/pinned_libs_32" + ":HOME/.local/share/Steam/ubuntu12_32/steam-runtime/pinned_libs_64" + ":HOME/.local/share/Steam/ubuntu12_32/steam-runtime/i386/lib/i386-linux-gnu" + ":HOME/.local/share/Steam/ubuntu12_32/steam-runtime/i386/lib" + ":HOME/.local/share/Steam/ubuntu12_32/steam-runtime/i386/usr/lib/i386-linux-gnu" + ":HOME/.local/share/Steam/ubuntu12_32/steam-runtime/i386/usr/lib" + ":HOME/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/lib/x86_64-linux-gnu" + ":HOME/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/lib" + ":HOME/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu" + ":HOME/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/usr/lib" + ); + library_path += ':'; library_path += qgetenv("LD_LIBRARY_PATH"); + ret.insert("LD_LIBRARY_PATH", library_path); + + ret.insert("WINEPREFIX", expand("HOME/.local/share/Steam/steamapps/compatdata/805550/pfx")); + ret.insert("WINEESYNC", "1"); + + return ret; +} + +QString proton_path(const QString& proton_version) +{ + QString wine_path = "HOME/.local/share/Steam/steamapps/common/Proton PROTON/dist/bin/wine"; + wine_path.replace("HOME", home_directory()); wine_path.replace("PROTON", proton_version); + return wine_path; +} + +#endif -- cgit v1.2.3