diff options
Diffstat (limited to 'proto-wine')
| -rw-r--r-- | proto-wine/CMakeLists.txt | 30 | ||||
| -rw-r--r-- | proto-wine/ftnoir_protocol_wine.cpp | 194 | ||||
| -rw-r--r-- | proto-wine/ftnoir_protocol_wine.h | 80 | ||||
| -rw-r--r-- | proto-wine/ftnoir_protocol_wine_dialog.cpp | 225 | ||||
| -rw-r--r-- | proto-wine/ftnoir_winecontrols.ui | 505 | ||||
| -rw-r--r-- | proto-wine/lang/de_DE.ts | 140 | ||||
| -rw-r--r-- | proto-wine/lang/nl_NL.ts | 129 | ||||
| -rw-r--r-- | proto-wine/lang/ru_RU.ts | 129 | ||||
| -rw-r--r-- | proto-wine/lang/stub.ts | 129 | ||||
| -rw-r--r-- | proto-wine/lang/zh_CN.ts | 140 | ||||
| -rw-r--r-- | proto-wine/opentrack-wrapper-wine-main.cxx | 14 | ||||
| -rw-r--r-- | proto-wine/opentrack-wrapper-wine-windows.cxx | 37 | ||||
| -rw-r--r-- | proto-wine/proton.cpp | 97 | ||||
| -rw-r--r-- | proto-wine/proton.h | 7 | ||||
| -rw-r--r-- | proto-wine/wine-shm.h | 12 |
15 files changed, 1638 insertions, 230 deletions
diff --git a/proto-wine/CMakeLists.txt b/proto-wine/CMakeLists.txt index 629f47f3..ff4932cc 100644 --- a/proto-wine/CMakeLists.txt +++ b/proto-wine/CMakeLists.txt @@ -1,27 +1,37 @@ if(NOT WIN32) - set(SDK_WINE_PREFIX "" CACHE PATH "Wine install prefix") - set(SDK_WINE_NO_WRAPPER FALSE CACHE BOOL "disable Wine wrapper -- use Wine only for X-Plane") - if(SDK_WINE_PREFIX) + set(SDK_WINE "" CACHE BOOL "Build for Wine") + set(no-wrapper FALSE) + if(NOT SDK_WINE AND SDK_XPLANE) + set(no-wrapper TRUE) + endif() + if(SDK_WINE OR no-wrapper) + if(no-wrapper) + add_definitions(-DOTR_WINE_NO_WRAPPER) + endif() otr_module(proto-wine) - target_link_libraries(opentrack-proto-wine opentrack-csv) - if(NOT SDK_WINE_NO_WRAPPER) + if(NOT no-wrapper) + target_link_libraries(opentrack-proto-wine opentrack-csv) set(my-rt -lrt) if(APPLE) set(my-rt) endif() file(GLOB wine-deps "${CMAKE_CURRENT_SOURCE_DIR}/*.cxx") - install(FILES ${wine-deps} DESTINATION "${opentrack-doc-src-pfx}/proto-wine") + #install(FILES ${wine-deps} DESTINATION "${opentrack-src}/proto-wine") + set(winegxx-multilib "-m32") + if (NOT OPENTRACK_WINE_ARCH STREQUAL "") + set(winegxx-multilib "${OPENTRACK_WINE_ARCH}") + endif() add_custom_command( OUTPUT opentrack-wrapper-wine.exe.so DEPENDS ${wine-deps} - COMMAND ${SDK_WINE_PREFIX}/bin/wineg++ -g -DNOMINMAX -O2 -m32 -std=c++14 -o + COMMAND wineg++ -mconsole -g -DNOMINMAX -O2 ${winegxx-multilib} -std=c++17 -fPIC -o opentrack-wrapper-wine.exe -I "${CMAKE_SOURCE_DIR}" -I "${CMAKE_BINARY_DIR}" - ${wine-deps} + ${wine-deps} -Wall -Wextra -Wpedantic ${my-rt}) - add_custom_target(wine-wrapper ALL DEPENDS opentrack-wrapper-wine.exe.so) + add_custom_target(wine-wrapper DEPENDS opentrack-wrapper-wine.exe.so) add_dependencies(opentrack-proto-wine wine-wrapper) add_dependencies(wine-wrapper opentrack-compat) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/opentrack-wrapper-wine.exe.so" DESTINATION ${opentrack-hier-pfx}) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/opentrack-wrapper-wine.exe.so" DESTINATION ${opentrack-libexec}) endif() endif() endif() diff --git a/proto-wine/ftnoir_protocol_wine.cpp b/proto-wine/ftnoir_protocol_wine.cpp index 42fb4896..bae02b06 100644 --- a/proto-wine/ftnoir_protocol_wine.cpp +++ b/proto-wine/ftnoir_protocol_wine.cpp @@ -1,48 +1,52 @@ #include "ftnoir_protocol_wine.h" +#include <qprocess.h> +#ifndef OTR_WINE_NO_WRAPPER +# include "csv/csv.h" +#endif + +#include <cstring> +#include <cmath> + #include <QString> -#include <QStringList> -#include <QCoreApplication> -#include <string.h> -#include <math.h> -#include <sys/mman.h> -#include <sys/stat.h> /* For mode constants */ -#include <fcntl.h> /* For O_* constants */ -#include "csv/csv.h" -#include "compat/macros.hpp" -#include "compat/library-path.hpp" - -wine::wine() : lck_shm(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)), shm(NULL), gameid(0) -{ - if (lck_shm.success()) { - shm = (WineSHM*) lck_shm.ptr(); - memset(shm, 0, sizeof(*shm)); - } - static const QString library_path(QCoreApplication::applicationDirPath() + OPENTRACK_LIBRARY_PATH); - wrapper.setWorkingDirectory(QCoreApplication::applicationDirPath()); - wrapper.start("wine", QStringList() << (library_path + "opentrack-wrapper-wine.exe.so")); -} +#include <QDebug> + +#include "proton.h" + +wine::wine() = default; wine::~wine() { +#ifndef OTR_WINE_NO_WRAPPER + bool exit = false; if (shm) { shm->stop = true; - wrapper.waitForFinished(100); + exit = wrapper.waitForFinished(100); + if (exit) + qDebug() << "proto/wine: wrapper exit code" << wrapper.exitCode(); + } + if (!exit) + { + if (wrapper.state() != QProcess::NotRunning) + wrapper.kill(); + wrapper.waitForFinished(1000); } - wrapper.close(); +#endif //shm_unlink("/" WINE_SHM_NAME); } -void wine::pose( const double *headpose ) +void wine::pose(const double *headpose, const double*) { if (shm) { lck_shm.lock(); for (int i = 3; i < 6; i++) - shm->data[i] = headpose[i] / (180 / M_PI ); + shm->data[i] = (headpose[i] * M_PI) / 180; for (int i = 0; i < 3; i++) shm->data[i] = headpose[i] * 10; +#ifndef OTR_WINE_NO_WRAPPER if (shm->gameid != gameid) { + //qDebug() << "proto/wine: looking up gameData"; QString gamename; QMutexLocker foo(&game_name_mutex); /* only EZCA for FSX requires dummy process, and FSX doesn't work on Linux */ @@ -51,16 +55,152 @@ void wine::pose( const double *headpose ) gameid = shm->gameid2 = shm->gameid; connected_game = gamename; } +#endif lck_shm.unlock(); } } module_status wine::initialize() { +#ifndef OTR_WINE_NO_WRAPPER + static const QString library_path(OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH); + + ///////////////////////// + // determine wine path // + ///////////////////////// + QString wine_path = "wine"; + + if (s.variant_wine) { + // NORMAL WINE + + // resolve combo box + if (s.wine_select_path().toString() != "WINE") { + // if we are not supposed to use system wine then: + if (s.wine_select_path().toString() != "CUSTOM") { + // if we don't have a custom path then change the wine_path to the path corresponding to the selected version + wine_path = s.wine_select_path().toString(); + } + else if (!s.wine_custom_path->isEmpty()) { + // if we do have a custom path and it is not empty then + wine_path = s.wine_custom_path; + } + } + + // parse tilde if present + if (wine_path[0] == '~') + wine_path = qgetenv("HOME") + wine_path.mid(1); + } + else if (s.variant_proton) + { + // PROTON + + wine_path = s.proton_path().toString() + "/bin/wine"; + } + qDebug() << "proto/wine: wine_path:" << wine_path; + + + ///////////////////////////////////// + // determine environment variables // + ///////////////////////////////////// + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + + // if proton is used setup proton environment + if (s.variant_proton) + { + auto [proton_env, env_error_string, env_success] = make_steam_environ(s.proton_path().toString()); + env = proton_env; + + if (!env_success) + return error(env_error_string); + } + + // determine wineprefix + if (s.variant_proton && s.variant_proton_steamplay) { + // wine prefix is dependend on steam + + if (s.proton_appid == 0) + return error(tr("Must specify application id for Proton (Steam Play)")); + + auto [prefix, error_string, success] = make_wineprefix(s.proton_appid); + qDebug() << "proto/wine: wineprefix:" << prefix; + env.insert("WINEPREFIX", prefix); + + if (!success) + return error(error_string); + } + else { + // wine prefix was supplied via path + + QString wineprefix = ""; + + // check if prefix was supplied via wine + if (s.variant_wine && !s.wineprefix->isEmpty()) + wineprefix = s.wineprefix; + + // check if prefix was supplied via proton + if (s.variant_proton_external && !s.protonprefix->isEmpty()) + wineprefix = s.protonprefix; + + // check if the user specified a prefix anywhere + if (wineprefix.isEmpty()) + return error(tr("Prefix has not been defined!").arg(wineprefix)); + + // handle tilde + if (wineprefix[0] == '~') + wineprefix = qgetenv("HOME") + wineprefix.mid(1); + + // return error if relative path is given + if (wineprefix[0] != '/') + return error(tr("Wine prefix must be an absolute path (given '%1')").arg(wineprefix)); + + qDebug() << "proto/wine: wineprefix:" << wineprefix; + + env.insert("WINEPREFIX", wineprefix); + } + + // ESYNC and FSYNC + if (s.esync) + env.insert("WINEESYNC", "1"); + if (s.fsync) + env.insert("WINEFSYNC", "1"); + + // Headtracking Protocol + env.insert("OTR_WINE_PROTO", QString::number(s.protocol+1)); + + + //////////////////////////////// + // launch the wrapper program // + //////////////////////////////// + + wrapper.setProcessEnvironment(env); + wrapper.setWorkingDirectory(OPENTRACK_BASE_PATH); + wrapper.start(wine_path, { library_path + "opentrack-wrapper-wine.exe.so" }); + wrapper.waitForStarted(); + if (wrapper.state() == QProcess::ProcessState::NotRunning) { + return error(tr("Failed to start Wine! Make sure the binary is set correctly.")); + } +#endif + + if (lck_shm.success()) + { + shm = (WineSHM*) lck_shm.ptr(); + memset(shm, 0, sizeof(*shm)); + + qDebug() << "proto/wine: shm success"; + + // display "waiting for game message" (overwritten once a game is detected) +#ifndef OTR_WINE_NO_WRAPPER + connected_game = "waiting for game..."; +#endif + } + else { + qDebug() << "proto/wine: shm no success"; + } + if (lck_shm.success()) return status_ok(); else - return error(otr_tr("Can't open shared memory mapping")); + return error(tr("Can't open shared memory mapping")); } -OPENTRACK_DECLARE_PROTOCOL(wine, FTControls, wineDll) +OPENTRACK_DECLARE_PROTOCOL(wine, FTControls, wine_metadata) diff --git a/proto-wine/ftnoir_protocol_wine.h b/proto-wine/ftnoir_protocol_wine.h index 0f300ff3..718699ac 100644 --- a/proto-wine/ftnoir_protocol_wine.h +++ b/proto-wine/ftnoir_protocol_wine.h @@ -1,43 +1,77 @@ #pragma once -#include "ui_ftnoir_winecontrols.h" -#include <QMessageBox> -#include <QLibrary> -#include <QProcess> -#include <QDebug> -#include <QMutex> -#include <QMutexLocker> -#include <QFile> #include "api/plugin-api.hpp" #include "compat/shm.h" #include "wine-shm.h" -class wine : public IProtocol +#include "ui_ftnoir_winecontrols.h" + +#include "options/options.hpp" +using namespace options; + +#include <QMutex> +#include <QProcess> +#include <QString> +#include <QVariant> + +#include <QDebug> + +struct settings : opts { + settings() : opts{"proto-wine"} {} + value<bool> variant_wine{b, "variant-wine", true }, + variant_proton{b, "variant-proton", false }, + variant_proton_steamplay{b, "variant-proton-steamplay", true }, + variant_proton_external{b, "variant-proton-external", false }, + fsync{b, "fsync", true}, + esync{b, "esync", true}; + + value<int> proton_appid{b, "proton-appid", 0}; + value<QVariant> proton_path{b, "proton-version", {} }; + value<QVariant> wine_select_path{b, "wine-select-version", {"WINE"}}; + value<QString> wine_custom_path{b, "wine-custom-version", ""}; + value<QString> wineprefix{b, "wineprefix", "~/.wine/"}; + value<QString> protonprefix{b, "protonprefix", ""}; + value<int> protocol{b, "protocol", 2}; +}; + +class wine : TR, public IProtocol +{ + Q_OBJECT + public: wine(); ~wine() override; module_status initialize() override; - void pose(const double* headpose) override; + void pose(const double* headpose, const double*) override; QString game_name() override { +#ifndef OTR_WINE_NO_WRAPPER QMutexLocker foo(&game_name_mutex); return connected_game; +#else + return QStringLiteral("X-Plane"); +#endif } private: - shm_wrapper lck_shm; - WineSHM* shm; + shm_wrapper lck_shm { WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM) }; + WineSHM* shm = nullptr; + settings s; + +#ifndef OTR_WINE_NO_WRAPPER QProcess wrapper; - int gameid; + int gameid = 0; QString connected_game; QMutex game_name_mutex; +#endif }; class FTControls: public IProtocolDialog { Q_OBJECT + public: FTControls(); void register_protocol(IProtocol *) override {} @@ -45,15 +79,31 @@ public: private: Ui::UICFTControls ui; + settings s; private slots: + void onWinePathComboUpdated(); + void onRadioButtonsChanged(); + + void doBrowseWine(); + void doBrowseWinePrefix(); + + void doBrowseProtonPrefix(); + void doOK(); void doCancel(); }; -class wineDll : public Metadata +class wine_metadata : public Metadata { + Q_OBJECT + public: - QString name() override { return QString("Wine -- Windows layer for Unix"); } +#ifndef OTR_WINE_NO_WRAPPER + QString name() override { return tr("Wine -- Windows layer for Unix"); } QIcon icon() override { return QIcon(":/images/wine.png"); } +#else + QString name() override { return tr("X-Plane"); } + QIcon icon() override { return {}; } +#endif }; diff --git a/proto-wine/ftnoir_protocol_wine_dialog.cpp b/proto-wine/ftnoir_protocol_wine_dialog.cpp index a388df70..2b7d08e0 100644 --- a/proto-wine/ftnoir_protocol_wine_dialog.cpp +++ b/proto-wine/ftnoir_protocol_wine_dialog.cpp @@ -1,19 +1,232 @@ #include "ftnoir_protocol_wine.h" #include <QDebug> +#include <QFileDialog> +#include <QDir> +#include <QDirIterator> +#include <qcombobox.h> +#include <qdebug.h> +#include <qdir.h> +#include <qradiobutton.h> + #include "api/plugin-api.hpp" +#include "options/tie.hpp" + +/* + * 0: path to the directory with wine versions + * 1: path from a wine version to the exectuable + * 2: name of the application using the wine versions + */ +static const char* wine_paths[][3] = { + {"/.local/share/lutris/runners/wine/", "/bin/wine", "Lutris"}, + {"/.var/app/net.lutris.Lutris/data/lutris/runners/wine/", "/bin/wine", "Flatpak Lutris"} +}; + +static const char* proton_paths[][2] = { + {"/.steam/steam/steamapps/common", "Proton*"}, + {"/.steam/root/compatibilitytools.d", "*"}, + {"/.local/share/Steam/steamapps/common", "Proton*"}, + {"/.local/share/Steam/compatibilitytools.d", "*"}, +}; FTControls::FTControls() { - ui.setupUi( this ); - connect(ui.btnOK, SIGNAL(clicked()), this, SLOT(doOK())); - connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); + ui.setupUi(this); + + // populate wine select + ui.wine_path_combo->addItem("System Wine", QVariant{"WINE"}); + for (const char** path : wine_paths) { + QDir dir(QDir::homePath() + path[0]); + dir.setFilter(QDir::Dirs); + QFileInfoList list = dir.entryInfoList(); + for (int i = 0; i < list.size(); ++i) { + QFileInfo fileInfo = list.at(i); + if (fileInfo.fileName() == "." || fileInfo.fileName() == "..") continue; + + QString name = fileInfo.fileName() + " (" + path[2] + ")"; + ui.wine_path_combo->addItem(name, QVariant{fileInfo.filePath() + path[1]}); + } + } + ui.wine_path_combo->addItem("Custom path to Wine executable", QVariant{"CUSTOM"}); + + // populate proton select + for (const char** path : proton_paths) { + QDir dir(QDir::homePath() + path[0]); + dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); + dir.setNameFilters({ path[1] }); + + QFileInfoList proton_dir_list = dir.entryInfoList(); + for (int i = 0; i < proton_dir_list.size(); ++i) { + const QFileInfo &proton_dir = proton_dir_list.at(i); + + // check if this Proton Version is already present in any way + if (ui.proton_version->findText(proton_dir.fileName()) != -1) + continue; + + QDirIterator proton_executable_it(proton_dir.canonicalFilePath(), QStringList() << "wine", QDir::Files, QDirIterator::Subdirectories); + + if (proton_executable_it.hasNext()) { + QString proton_executable_path = proton_executable_it.next(); + QDir proton_dist_dir(proton_executable_path); + proton_dist_dir.cd("../../"); + + ui.proton_version->addItem(proton_dir.fileName(), QVariant{proton_dist_dir.canonicalPath()}); + } + } + } + + // settings - wine + tie_setting(s.variant_wine, ui.variant_wine); // radio button + tie_setting(s.wine_select_path, ui.wine_path_combo); // combo box (dropdown) + tie_setting(s.wine_custom_path, ui.wine_path); // line edit (enabled via dropdown) + tie_setting(s.wineprefix, ui.wineprefix); // line edit + + // settings - proton + tie_setting(s.variant_proton, ui.variant_proton); // radio button + tie_setting(s.proton_path, ui.proton_version); // combo box (dropdown) + tie_setting(s.variant_proton_steamplay, ui.subvariant_steamplay); // radio button + tie_setting(s.proton_appid, ui.proton_appid); // number select + tie_setting(s.variant_proton_external, ui.subvariant_external); // radio button + tie_setting(s.protonprefix, ui.protonprefix); // line edit + + // settings - advanced + tie_setting(s.esync, ui.esync); + tie_setting(s.fsync, ui.fsync); + tie_setting(s.protocol, ui.protocol_selection); + + // setup signals and slots for UI + connect(ui.wine_path_combo, &QComboBox::currentTextChanged, this, &FTControls::onWinePathComboUpdated); + connect(ui.browse_wine_path_button, &QPushButton::clicked, this, &FTControls::doBrowseWine); + connect(ui.browse_wine_prefix_button, &QPushButton::clicked, this, &FTControls::doBrowseWinePrefix); + connect(ui.browse_proton_prefix_button, &QPushButton::clicked, this, &FTControls::doBrowseProtonPrefix); + connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &FTControls::doOK); + connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &FTControls::doCancel); + + // setup signals and slots for UI radio buttons + connect(ui.variant_wine, &QRadioButton::clicked, this, &FTControls::onRadioButtonsChanged); + connect(ui.variant_proton, &QRadioButton::clicked, this, &FTControls::onRadioButtonsChanged); + connect(ui.subvariant_steamplay, &QRadioButton::clicked, this, &FTControls::onRadioButtonsChanged); + connect(ui.subvariant_external, &QRadioButton::clicked, this, &FTControls::onRadioButtonsChanged); + + // update state of the combo box and associated ui elements + onWinePathComboUpdated(); + // hide the correct items + onRadioButtonsChanged(); } -void FTControls::doOK() { - close(); +void FTControls::onWinePathComboUpdated() { + // enable the custom text field if required + if (ui.wine_path_combo->currentData() == "CUSTOM") { + ui.wine_path->setEnabled(true); + ui.browse_wine_path_button->setEnabled(true); + } + else { + ui.wine_path->setEnabled(false); + ui.browse_wine_path_button->setEnabled(false); + } } -void FTControls::doCancel() { +void FTControls::onRadioButtonsChanged() { + if (ui.variant_wine->isChecked()) { + // wine settings selected + + // enable wine settings + ui.wine_path_combo->setEnabled(true); + ui.wineprefix->setEnabled(true); + ui.browse_wine_prefix_button->setEnabled(true); + if (ui.wine_path_combo->currentData() == "CUSTOM") { + ui.wine_path->setEnabled(true); + ui.browse_wine_path_button->setEnabled(true); + } + + // disable proton settings + ui.proton_version->setEnabled(false); + ui.proton_subgroup->setEnabled(false); + } + else if (ui.variant_proton->isChecked()) { + // proton settings selected + + // disable wine settings + ui.wine_path_combo->setEnabled(false); + ui.wine_path->setEnabled(false); + ui.browse_wine_path_button->setEnabled(false); + ui.wineprefix->setEnabled(false); + ui.browse_wine_prefix_button->setEnabled(false); + + // enable proton settings + ui.proton_version->setEnabled(true); + ui.proton_subgroup->setEnabled(true); + + // run proton radio buttons logic + if (ui.subvariant_steamplay->isChecked()) { + // enable steamplay settings + ui.proton_appid->setEnabled(true); + + // disable external settings + ui.protonprefix->setEnabled(false); + ui.browse_proton_prefix_button->setEnabled(false); + } + else if (ui.subvariant_external->isChecked()) { + // disable steamplay settings + ui.proton_appid->setEnabled(false); + + // enable external settinsg + ui.protonprefix->setEnabled(true); + ui.browse_proton_prefix_button->setEnabled(true); + } + } + else { + // for some reason QTs auto exclusive feature is not always correctly working + // this is a somewhat hacky solution + ui.variant_wine->setChecked(ui.wine_path_combo->isEnabled()); + ui.variant_proton->setChecked(ui.proton_version->isEnabled()); + } +} + +void FTControls::doBrowseWine() { + QFileDialog d(this); + d.setFileMode(QFileDialog::FileMode::ExistingFile); + d.setWindowTitle(tr("Select path to Wine Binary")); + if (s.wine_custom_path->startsWith("~/.local/share/lutris/runners")) { + d.selectFile(s.wine_custom_path); + } + if (d.exec()) { + s.wine_custom_path = d.selectedFiles()[0]; + } +} +void FTControls::doBrowseWinePrefix() { + QFileDialog d(this); + d.setFileMode(QFileDialog::FileMode::Directory); + d.setOption(QFileDialog::Option::ShowDirsOnly, true); + d.setWindowTitle(tr("Select Wine Prefix")); + if (s.wineprefix->startsWith("/") || s.wineprefix->startsWith("~")) { + d.selectFile(s.wineprefix); + } + if (d.exec()) { + s.wineprefix = d.selectedFiles()[0]; + } +} + +void FTControls::doBrowseProtonPrefix() { + QFileDialog d(this); + d.setFileMode(QFileDialog::FileMode::Directory); + d.setOption(QFileDialog::Option::ShowDirsOnly, true); + d.setWindowTitle(tr("Select Proton Prefix")); + if (s.protonprefix->startsWith("/") || s.protonprefix->startsWith("~")) { + d.selectFile(s.protonprefix); + } + if (d.exec()) { + s.protonprefix = d.selectedFiles()[0]; + } +} + +void FTControls::doOK() +{ + s.b->save(); close(); } +void FTControls::doCancel() +{ + s.b->reload(); + close(); +} diff --git a/proto-wine/ftnoir_winecontrols.ui b/proto-wine/ftnoir_winecontrols.ui index 9356c448..b601d6e5 100644 --- a/proto-wine/ftnoir_winecontrols.ui +++ b/proto-wine/ftnoir_winecontrols.ui @@ -9,16 +9,16 @@ <rect> <x>0</x> <y>0</y> - <width>409</width> - <height>110</height> + <width>934</width> + <height>466</height> </rect> </property> <property name="windowTitle"> - <string>FreeTrack settings FaceTrackNoIR</string> + <string>Wine settings</string> </property> <property name="windowIcon"> - <iconset> - <normaloff>images/freetrack.png</normaloff>images/freetrack.png</iconset> + <iconset resource="wine-protocol.qrc"> + <normaloff>:/images/wine.png</normaloff>:/images/wine.png</iconset> </property> <property name="layoutDirection"> <enum>Qt::LeftToRight</enum> @@ -26,141 +26,388 @@ <property name="autoFillBackground"> <bool>false</bool> </property> - <layout class="QVBoxLayout" name="_vertical_layout"> + <layout class="QVBoxLayout" name="verticalLayout"> <item> - <layout class="QHBoxLayout"> - <item> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Wine variant</string> </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="1" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLineEdit" name="wine_path"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>450</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>wine/runner exectuable path</p></body></html></string> + </property> + <property name="inputMask"> + <string/> + </property> + <property name="placeholderText"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="browse_wine_path_button"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Browse Wine Path</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="2" column="1"> + <layout class="QVBoxLayout" name="verticalLayout_7"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QLineEdit" name="wineprefix"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>450</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string><html><head/><body><p>prefix</p></body></html></string> + </property> + <property name="placeholderText"> + <string>/path_to_the_prefix/</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="browse_wine_prefix_button"> + <property name="text"> + <string>Browse Prefix</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="proton_version"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>120</width> + <height>0</height> + </size> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QRadioButton" name="variant_proton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Proton (select version and mode)</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QRadioButton" name="variant_wine"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Wine (select version and prefix)</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="wine_path_combo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QGroupBox" name="proton_subgroup"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="1"> + <widget class="QSpinBox" name="proton_appid"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QRadioButton" name="subvariant_steamplay"> + <property name="toolTip"> + <string><html><head/><body><p>Steam Play is Steams System to run Windows titles on Linux via Proton.</p></body></html></string> + </property> + <property name="text"> + <string>Steam Play (select Steam Application ID)</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QRadioButton" name="subvariant_external"> + <property name="toolTip"> + <string><html><head/><body><p>UMU is a launcher that allows the use of Proton outside of Steam. Some game launchers like Lutris may use this to enable Proton support.</p></body></html></string> + </property> + <property name="text"> + <string>UMU enabled Launchers (select prefix)</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_7"> + <item> + <widget class="QLineEdit" name="protonprefix"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>450</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="browse_proton_prefix_button"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>105</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Browse Prefix</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> </item> <item> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>There are no settings necessary for the Wine protocol.</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> - </property> - <item> - <widget class="QPushButton" name="btnOK"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>100</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>OK</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="btnCancel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Advanced</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <widget class="QCheckBox" name="esync"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string><html><head/><body><p>When supported.</p></body></html></string> + </property> + <property name="text"> + <string>ESYNC</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="fsync"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string><html><head/><body><p>When supported.</p></body></html></string> + </property> + <property name="text"> + <string>FSYNC</string> + </property> + </widget> + </item> + <item> + <widget class="QWidget" name="widget_2" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="topMargin"> + <number>0</number> </property> - <property name="minimumSize"> - <size> - <width>100</width> - <height>0</height> - </size> + <property name="bottomMargin"> + <number>0</number> </property> - <property name="maximumSize"> - <size> - <width>100</width> - <height>16777215</height> - </size> + <item> + <widget class="QLabel" name="label_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Protocol</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="protocol_selection"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <item> + <property name="text"> + <string>Freetrack</string> + </property> + </item> + <item> + <property name="text"> + <string>NPClient</string> + </property> + </item> + <item> + <property name="text"> + <string>Both</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" name="widget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="topMargin"> + <number>0</number> </property> - <property name="text"> - <string>Cancel</string> + <property name="bottomMargin"> + <number>0</number> </property> - </widget> - </item> - </layout> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>10</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> </item> </layout> </widget> - <resources/> + <tabstops> + <tabstop>variant_wine</tabstop> + <tabstop>wine_path_combo</tabstop> + <tabstop>wine_path</tabstop> + <tabstop>browse_wine_path_button</tabstop> + <tabstop>wineprefix</tabstop> + <tabstop>browse_wine_prefix_button</tabstop> + <tabstop>variant_proton</tabstop> + <tabstop>proton_version</tabstop> + <tabstop>subvariant_steamplay</tabstop> + <tabstop>proton_appid</tabstop> + <tabstop>subvariant_external</tabstop> + <tabstop>protonprefix</tabstop> + <tabstop>browse_proton_prefix_button</tabstop> + <tabstop>esync</tabstop> + <tabstop>fsync</tabstop> + <tabstop>protocol_selection</tabstop> + </tabstops> + <resources> + <include location="wine-protocol.qrc"/> + </resources> <connections/> <slots> <slot>startEngineClicked()</slot> diff --git a/proto-wine/lang/de_DE.ts b/proto-wine/lang/de_DE.ts new file mode 100644 index 00000000..072c8626 --- /dev/null +++ b/proto-wine/lang/de_DE.ts @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="de_DE"> +<context> + <name>FTControls</name> + <message> + <source>Select path to Wine Binary</source> + <translation>Pfad des wine-Programms auswählen</translation> + </message> + <message> + <source>Select Wine Prefix</source> + <translation>wine-Prefix auswählen</translation> + </message> + <message> + <source>Select Proton Prefix</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>UICFTControls</name> + <message> + <source>Wine settings</source> + <translation>Wine-Einstellungen</translation> + </message> + <message> + <source>Wine variant</source> + <translation>Wine-Variante</translation> + </message> + <message> + <source><html><head/><body><p>prefix</p></body></html></source> + <translation><html><head/><body><p>Prefix</p></body></html></translation> + </message> + <message> + <source>/path_to_the_prefix/</source> + <translation>/pfad_zum_prefix/</translation> + </message> + <message> + <source>Browse Prefix</source> + <translation>Prefix suchen</translation> + </message> + <message> + <source><html><head/><body><p>wine/runner exectuable path</p></body></html></source> + <translation><html><head/><body><p>Pfad zum ausführbaren wine/runner</p></body></html></translation> + </message> + <message> + <source>Browse Wine Path</source> + <translation>Wine-Pfad suchen</translation> + </message> + <message> + <source>Advanced</source> + <translation>Erweitert</translation> + </message> + <message> + <source><html><head/><body><p>When supported.</p></body></html></source> + <translation><html><head/><body><p>Falls unterstützt.</p></body></html></translation> + </message> + <message> + <source>ESYNC</source> + <translation>ESYNC</translation> + </message> + <message> + <source>FSYNC</source> + <translation>FSYNC</translation> + </message> + <message> + <source>Protocol</source> + <translation>Protokoll</translation> + </message> + <message> + <source>Freetrack</source> + <translation>Freetrack</translation> + </message> + <message> + <source>NPClient</source> + <translation>NPClient</translation> + </message> + <message> + <source>Both</source> + <translation>Beides</translation> + </message> + <message> + <source>Proton (select version and mode)</source> + <translation>Proton (wähle Version und Modus)</translation> + </message> + <message> + <source>Steam Play (select Steam Application ID)</source> + <translation>Steam Play (wähle Steam Applikation ID)</translation> + </message> + <message> + <source>UMU enabled Launchers (select prefix)</source> + <translation>UMU unterstützte Launcher (wähle Prefix)</translation> + </message> + <message> + <source>Wine (select version and prefix)</source> + <translation>Wine (wähle Version und Prefix)</translation> + </message> + <message> + <source><html><head/><body><p>Steam Play is Steams System to run Windows titles on Linux via Proton.</p></body></html></source> + <translation><html><head/><body><p>Steam Play ist Steams System, um Windows Titel auf Linux, via Proton, auszuführen.</p></body></html></translation> + </message> + <message> + <source><html><head/><body><p>UMU is a launcher that allows the use of Proton outside of Steam. Some game launchers like Lutris may use this to enable Proton support.</p></body></html></source> + <translation><html><head/><body><p>UMU ist ein Launcher, der es erlaubt Proton außerhalb von Steam zu nutzen. Manche Spiel Launcher, wie Lutris, können dies für Proton Support nutzen.</p></body></html></translation> + </message> +</context> +<context> + <name>wine</name> + <message> + <source>Must specify application id for Proton (Steam Play)</source> + <translation>Die Application-ID für Proton (Steam Play) muss angegeben werden</translation> + </message> + <message> + <source>Wine prefix must be an absolute path (given '%1')</source> + <translation>Wine-Prefix muss ein absoluter Pfad sein ('%1' angegeben)</translation> + </message> + <message> + <source>Failed to start Wine! Make sure the binary is set correctly.</source> + <translation>Starten von Wine fehlgeschlagen! Stelle sicher, dass der Programmpfad richtig gesetzt ist.</translation> + </message> + <message> + <source>Can't open shared memory mapping</source> + <translation>Shared-Memory-Mapping kann nicht geöffnet werden</translation> + </message> + <message> + <source>Prefix has not been defined!</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>wine_metadata</name> + <message> + <source>Wine -- Windows layer for Unix</source> + <translation>Wine -- Windows-Schicht für Unix</translation> + </message> + <message> + <source>X-Plane</source> + <translation>X-Plane</translation> + </message> +</context> +</TS> diff --git a/proto-wine/lang/nl_NL.ts b/proto-wine/lang/nl_NL.ts index 4afcafa8..bc3ef604 100644 --- a/proto-wine/lang/nl_NL.ts +++ b/proto-wine/lang/nl_NL.ts @@ -2,25 +2,138 @@ <!DOCTYPE TS> <TS version="2.1" language="nl_NL"> <context> + <name>FTControls</name> + <message> + <source>Select path to Wine Binary</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Select Wine Prefix</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Select Proton Prefix</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>UICFTControls</name> <message> - <location filename="../ftnoir_winecontrols.ui" line="+17"/> - <source>FreeTrack settings FaceTrackNoIR</source> + <source>Wine settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine variant</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Advanced</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>ESYNC</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>FSYNC</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>When supported.</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Protocol</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Freetrack</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>NPClient</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Both</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>prefix</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>/path_to_the_prefix/</source> <translation type="unfinished"></translation> </message> <message> - <location line="+48"/> - <source>There are no settings necessary for the Wine protocol.</source> + <source>Browse Prefix</source> <translation type="unfinished"></translation> </message> <message> - <location line="+47"/> - <source>OK</source> + <source><html><head/><body><p>wine/runner exectuable path</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Browse Wine Path</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Proton (select version and mode)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Steam Play (select Steam Application ID)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>UMU enabled Launchers (select prefix)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine (select version and prefix)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>Steam Play is Steams System to run Windows titles on Linux via Proton.</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>UMU is a launcher that allows the use of Proton outside of Steam. Some game launchers like Lutris may use this to enable Proton support.</p></body></html></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>wine</name> + <message> + <source>Can't open shared memory mapping</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Must specify application id for Proton (Steam Play)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine prefix must be an absolute path (given '%1')</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Failed to start Wine! Make sure the binary is set correctly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Prefix has not been defined!</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>wine_metadata</name> + <message> + <source>Wine -- Windows layer for Unix</source> <translation type="unfinished"></translation> </message> <message> - <location line="+25"/> - <source>Cancel</source> + <source>X-Plane</source> <translation type="unfinished"></translation> </message> </context> diff --git a/proto-wine/lang/ru_RU.ts b/proto-wine/lang/ru_RU.ts index 1fc4ce25..a7702454 100644 --- a/proto-wine/lang/ru_RU.ts +++ b/proto-wine/lang/ru_RU.ts @@ -2,25 +2,138 @@ <!DOCTYPE TS> <TS version="2.1" language="ru_RU"> <context> + <name>FTControls</name> + <message> + <source>Select path to Wine Binary</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Select Wine Prefix</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Select Proton Prefix</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>UICFTControls</name> <message> - <location filename="../ftnoir_winecontrols.ui" line="+17"/> - <source>FreeTrack settings FaceTrackNoIR</source> + <source>Wine settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine variant</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Advanced</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>ESYNC</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>FSYNC</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>When supported.</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Protocol</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Freetrack</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>NPClient</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Both</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>prefix</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>/path_to_the_prefix/</source> <translation type="unfinished"></translation> </message> <message> - <location line="+48"/> - <source>There are no settings necessary for the Wine protocol.</source> + <source>Browse Prefix</source> <translation type="unfinished"></translation> </message> <message> - <location line="+47"/> - <source>OK</source> + <source><html><head/><body><p>wine/runner exectuable path</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Browse Wine Path</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Proton (select version and mode)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Steam Play (select Steam Application ID)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>UMU enabled Launchers (select prefix)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine (select version and prefix)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>Steam Play is Steams System to run Windows titles on Linux via Proton.</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>UMU is a launcher that allows the use of Proton outside of Steam. Some game launchers like Lutris may use this to enable Proton support.</p></body></html></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>wine</name> + <message> + <source>Can't open shared memory mapping</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Must specify application id for Proton (Steam Play)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine prefix must be an absolute path (given '%1')</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Failed to start Wine! Make sure the binary is set correctly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Prefix has not been defined!</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>wine_metadata</name> + <message> + <source>Wine -- Windows layer for Unix</source> <translation type="unfinished"></translation> </message> <message> - <location line="+25"/> - <source>Cancel</source> + <source>X-Plane</source> <translation type="unfinished"></translation> </message> </context> diff --git a/proto-wine/lang/stub.ts b/proto-wine/lang/stub.ts index bcd7fb82..2c708749 100644 --- a/proto-wine/lang/stub.ts +++ b/proto-wine/lang/stub.ts @@ -2,25 +2,138 @@ <!DOCTYPE TS> <TS version="2.1"> <context> + <name>FTControls</name> + <message> + <source>Select path to Wine Binary</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Select Wine Prefix</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Select Proton Prefix</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>UICFTControls</name> <message> - <location filename="../ftnoir_winecontrols.ui" line="+17"/> - <source>FreeTrack settings FaceTrackNoIR</source> + <source>Wine settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine variant</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Advanced</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>ESYNC</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>FSYNC</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>When supported.</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Protocol</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Freetrack</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>NPClient</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Both</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>prefix</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>/path_to_the_prefix/</source> <translation type="unfinished"></translation> </message> <message> - <location line="+48"/> - <source>There are no settings necessary for the Wine protocol.</source> + <source>Browse Prefix</source> <translation type="unfinished"></translation> </message> <message> - <location line="+47"/> - <source>OK</source> + <source><html><head/><body><p>wine/runner exectuable path</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Browse Wine Path</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Proton (select version and mode)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Steam Play (select Steam Application ID)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>UMU enabled Launchers (select prefix)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine (select version and prefix)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>Steam Play is Steams System to run Windows titles on Linux via Proton.</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>UMU is a launcher that allows the use of Proton outside of Steam. Some game launchers like Lutris may use this to enable Proton support.</p></body></html></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>wine</name> + <message> + <source>Can't open shared memory mapping</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Must specify application id for Proton (Steam Play)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine prefix must be an absolute path (given '%1')</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Failed to start Wine! Make sure the binary is set correctly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Prefix has not been defined!</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>wine_metadata</name> + <message> + <source>Wine -- Windows layer for Unix</source> <translation type="unfinished"></translation> </message> <message> - <location line="+25"/> - <source>Cancel</source> + <source>X-Plane</source> <translation type="unfinished"></translation> </message> </context> diff --git a/proto-wine/lang/zh_CN.ts b/proto-wine/lang/zh_CN.ts new file mode 100644 index 00000000..6884f266 --- /dev/null +++ b/proto-wine/lang/zh_CN.ts @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="zh_CN"> +<context> + <name>FTControls</name> + <message> + <source>Select path to Wine Binary</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Select Wine Prefix</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Select Proton Prefix</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>UICFTControls</name> + <message> + <source>Wine settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine variant</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Advanced</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>ESYNC</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>FSYNC</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>When supported.</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Protocol</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Freetrack</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>NPClient</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Both</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>prefix</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>/path_to_the_prefix/</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Browse Prefix</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>wine/runner exectuable path</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Browse Wine Path</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Proton (select version and mode)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Steam Play (select Steam Application ID)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>UMU enabled Launchers (select prefix)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine (select version and prefix)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>Steam Play is Steams System to run Windows titles on Linux via Proton.</p></body></html></source> + <translation type="unfinished"></translation> + </message> + <message> + <source><html><head/><body><p>UMU is a launcher that allows the use of Proton outside of Steam. Some game launchers like Lutris may use this to enable Proton support.</p></body></html></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>wine</name> + <message> + <source>Can't open shared memory mapping</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Must specify application id for Proton (Steam Play)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wine prefix must be an absolute path (given '%1')</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Failed to start Wine! Make sure the binary is set correctly.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Prefix has not been defined!</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>wine_metadata</name> + <message> + <source>Wine -- Windows layer for Unix</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>X-Plane</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/proto-wine/opentrack-wrapper-wine-main.cxx b/proto-wine/opentrack-wrapper-wine-main.cxx index 1c88755a..9248a212 100644 --- a/proto-wine/opentrack-wrapper-wine-main.cxx +++ b/proto-wine/opentrack-wrapper-wine-main.cxx @@ -1,18 +1,19 @@ #include <cerrno> + // OSX sdk 10.8 build error otherwise -#ifdef _LIBCPP_MSVCRT -# undef _LIBCPP_MSVCRT -#endif +#undef _LIBCPP_MSVCRT #include <cstdio> + #include "freetrackclient/fttypes.h" -#include "wine-shm.h" #include "compat/export.hpp" enum Axis { TX = 0, TY, TZ, Yaw, Pitch, Roll }; +#define __WINE_OLE2_H #include "compat/shm.h" +#include "wine-shm.h" void create_registry_key(void); @@ -41,18 +42,17 @@ private: void* mem; void *hMutex, *hMapFile; }; -#include <windows.h> int main(void) { ShmPosix lck_posix(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)); ShmWine lck_wine("FT_SharedMem", "FT_Mutext", sizeof(FTHeap)); if(!lck_posix.success()) { - printf("Can't open posix map: %d\n", errno); + fprintf(stderr, "Can't open posix map: %d\n", errno); return 1; } if(!lck_wine.success()) { - printf("Can't open Wine map\n"); + fprintf(stderr, "Can't open Wine map\n"); return 1; } WineSHM* shm_posix = (WineSHM*) lck_posix.ptr(); diff --git a/proto-wine/opentrack-wrapper-wine-windows.cxx b/proto-wine/opentrack-wrapper-wine-windows.cxx index e1f91797..c1d552e1 100644 --- a/proto-wine/opentrack-wrapper-wine-windows.cxx +++ b/proto-wine/opentrack-wrapper-wine-windows.cxx @@ -3,19 +3,23 @@ #endif #define shm_wrapper ShmWine +#define __WINE_OLE2_H +// OSX sdk 10.8 build error otherwise +#undef _LIBCPP_MSVCRT + #include "compat/shm.h" #include "compat/shm.cpp" #include "wine-shm.h" -#define OPENTRACK_NO_QT_PATH #include "compat/library-path.hpp" +#include <cstdlib> #include <cstring> +#include <sysexits.h> using std::strcat; -static void write_path(const char* key, const char* subkey) +static void write_path(const char* key, const char* subkey, bool path) { - char dir[8192]; - dir[sizeof(dir)-1] = '\0'; + char dir[8192] {}; if (GetCurrentDirectoryA(8192, dir) < 8190) { @@ -36,13 +40,32 @@ static void write_path(const char* key, const char* subkey) // there's always a leading and trailing slash strcat(dir, OPENTRACK_LIBRARY_PATH); //strcat(dir, "/"); + if (!path) + dir[0] = '\0'; (void) RegSetValueExA(hkpath, subkey, 0, REG_SZ, (BYTE*) dir, strlen(dir) + 1); RegCloseKey(hkpath); } } } -void create_registry_key(void) { - write_path("Software\\NaturalPoint\\NATURALPOINT\\NPClient Location", "Path"); - write_path("Software\\Freetrack\\FreeTrackClient", "Path"); +void create_registry_key(void) +{ + bool use_freetrack, use_npclient; + const char* env = getenv("OTR_WINE_PROTO"); + char* endptr; + if (!env) env = ""; + int selection = strtol(env, &endptr, 10); + if (*endptr) + selection = 0; + + switch (selection) + { + default: std::exit(EX_USAGE); + case 1: use_freetrack = true, use_npclient = false; break; + case 2: use_freetrack = false, use_npclient = true; break; + case 3: use_freetrack = true, use_npclient = true; break; + } + + write_path("Software\\NaturalPoint\\NATURALPOINT\\NPClient Location", "Path", use_npclient); + write_path("Software\\Freetrack\\FreeTrackClient", "Path", use_freetrack); } diff --git a/proto-wine/proton.cpp b/proto-wine/proton.cpp new file mode 100644 index 00000000..998da748 --- /dev/null +++ b/proto-wine/proton.cpp @@ -0,0 +1,97 @@ +/* Copyright (c) 2019 Stanislaw Halik <sthalik@misaki.pl> + * + * 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 <QDebug> +#include <QDir> +#include <QFileInfo> +#include <QtGlobal> + +#include "proton.h" + +static const char* steam_paths[] = { + "/.steam/steam/steamapps/compatdata", + "/.local/share/Steam/steamapps/compatdata", + "/.steam/debian-installation/steamapps/compatdata", +}; + +static const char* runtime_paths[] = { + "/.local/share/Steam/ubuntu12_32/steam-runtime", + "/.steam/ubuntu12_32/steam-runtime", + "/.steam/debian-installation/ubuntu12_32/steam-runtime", +}; + + +std::tuple<QProcessEnvironment, QString, bool> make_steam_environ(const QString& proton_dist_path) +{ + using ret = std::tuple<QProcessEnvironment, QString, bool>; + auto env = QProcessEnvironment::systemEnvironment(); + QString error = ""; + QString home = qgetenv("HOME"); + QString runtime_path; + + auto expand = [&](QString x) { + x.replace("HOME", home); + x.replace("PROTON_DIST_PATH", proton_dist_path); + x.replace("RUNTIME_PATH", runtime_path); + return x; + }; + + for (const char* path : runtime_paths) { + QDir dir(QDir::homePath() + path); + if (dir.exists()) + runtime_path = dir.absolutePath(); + } + + if (runtime_path.isEmpty()) + error = QString("Couldn't find a Steam runtime."); + + QString path = expand( + ":PROTON_DIST_PATH/bin" + ); + path += ':'; path += qgetenv("PATH"); + env.insert("PATH", path); + + QString library_path = expand( + ":PROTON_DIST_PATH/lib" + ":PROTON_DIST_PATH/lib64" + ":RUNTIME_PATH/pinned_libs_32" + ":RUNTIME_PATH/pinned_libs_64" + ":RUNTIME_PATH/i386/lib/i386-linux-gnu" + ":RUNTIME_PATH/i386/lib" + ":RUNTIME_PATH/i386/usr/lib/i386-linux-gnu" + ":RUNTIME_PATH/i386/usr/lib" + ":RUNTIME_PATH/amd64/lib/x86_64-linux-gnu" + ":RUNTIME_PATH/amd64/lib" + ":RUNTIME_PATH/amd64/usr/lib/x86_64-linux-gnu" + ":RUNTIME_PATH/amd64/usr/lib" + ); + library_path += ':'; library_path += qgetenv("LD_LIBRARY_PATH"); + env.insert("LD_LIBRARY_PATH", library_path); + + return ret(env, error, error.isEmpty()); +} + + +std::tuple<QString, QString, bool> make_wineprefix(int appid) +{ + using ret = std::tuple<QString, QString, bool>; + QString error = ""; + QString app_wineprefix; + for (const char* path : steam_paths) { + QDir dir(QDir::homePath() + path + QString("/%1/pfx").arg(appid)); + if (dir.exists()) + app_wineprefix = dir.absolutePath(); + } + if (app_wineprefix.isEmpty()) + error = QString("Couldn't find a Wineprefix for AppId %1").arg(appid); + + return ret(app_wineprefix, error, error.isEmpty()); +} + +#endif diff --git a/proto-wine/proton.h b/proto-wine/proton.h new file mode 100644 index 00000000..51539305 --- /dev/null +++ b/proto-wine/proton.h @@ -0,0 +1,7 @@ +#pragma once + +#include <qchar.h> +#include <qprocess.h> + +std::tuple<QProcessEnvironment, QString, bool> make_steam_environ(const QString& proton_dist_path); +std::tuple<QString, QString, bool> make_wineprefix(int appid);
\ No newline at end of file diff --git a/proto-wine/wine-shm.h b/proto-wine/wine-shm.h index a717dcc8..62e8bbec 100644 --- a/proto-wine/wine-shm.h +++ b/proto-wine/wine-shm.h @@ -3,12 +3,14 @@ #define WINE_SHM_NAME "facetracknoir-wine-shm" #define WINE_MTX_NAME "facetracknoir-wine-mtx" -// OSX sdk 10.8 build error otherwise -#undef _LIBCPP_MSVCRT +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wreserved-id-macro" +#endif -#include <memory> - -template<typename t> using ptr = std::shared_ptr<t>; +#ifdef __clang__ +# pragma clang diagnostic pop +#endif struct WineSHM { double data[6]; |
