Browse Source
[gamemode] Make available on other platforms (#353)
[gamemode] Make available on other platforms (#353)
Signed-off-by: lizzie <lizzie@eden-emu.dev> Co-authored-by: crueter <crueter@eden-emu.dev> Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/353 Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>pull/3160/head
committed by
crueter
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
29 changed files with 123 additions and 775 deletions
-
5CMakeLists.txt
-
6externals/CMakeLists.txt
-
7externals/cpmfile.json
-
376externals/gamemode/gamemode_client.h
-
6src/common/CMakeLists.txt
-
40src/common/linux/gamemode.cpp
-
24src/common/linux/gamemode.h
-
2src/common/settings.cpp
-
7src/common/settings.h
-
4src/common/settings_common.h
-
26src/frontend_common/config.cpp
-
6src/frontend_common/config.h
-
4src/qt_common/CMakeLists.txt
-
6src/qt_common/config/shared_translation.cpp
-
13src/qt_common/config/uisettings.h
-
52src/qt_common/gamemode.cpp
-
14src/qt_common/gamemode.h
-
3src/yuzu/CMakeLists.txt
-
15src/yuzu/configuration/configure_general.cpp
-
27src/yuzu/configuration/configure_general.ui
-
75src/yuzu/configuration/configure_linux_tab.cpp
-
44src/yuzu/configuration/configure_linux_tab.h
-
53src/yuzu/configuration/configure_linux_tab.ui
-
9src/yuzu/configuration/configure_per_game.cpp
-
2src/yuzu/configuration/configure_per_game.h
-
4src/yuzu/main.cpp
-
52src/yuzu/main_window.cpp
-
2src/yuzu/main_window.h
-
14src/yuzu_cmd/yuzu.cpp
@ -1,376 +0,0 @@ |
|||
/* |
|||
|
|||
Copyright (c) 2017-2019, Feral Interactive |
|||
All rights reserved. |
|||
|
|||
Redistribution and use in source and binary forms, with or without |
|||
modification, are permitted provided that the following conditions are met: |
|||
|
|||
* Redistributions of source code must retain the above copyright notice, |
|||
this list of conditions and the following disclaimer. |
|||
* Redistributions in binary form must reproduce the above copyright |
|||
notice, this list of conditions and the following disclaimer in the |
|||
documentation and/or other materials provided with the distribution. |
|||
* Neither the name of Feral Interactive nor the names of its contributors |
|||
may be used to endorse or promote products derived from this software |
|||
without specific prior written permission. |
|||
|
|||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
|||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|||
POSSIBILITY OF SUCH DAMAGE. |
|||
|
|||
*/ |
|||
#ifndef CLIENT_GAMEMODE_H |
|||
#define CLIENT_GAMEMODE_H |
|||
/* |
|||
* GameMode supports the following client functions |
|||
* Requests are refcounted in the daemon |
|||
* |
|||
* int gamemode_request_start() - Request gamemode starts |
|||
* 0 if the request was sent successfully |
|||
* -1 if the request failed |
|||
* |
|||
* int gamemode_request_end() - Request gamemode ends |
|||
* 0 if the request was sent successfully |
|||
* -1 if the request failed |
|||
* |
|||
* GAMEMODE_AUTO can be defined to make the above two functions apply during static init and |
|||
* destruction, as appropriate. In this configuration, errors will be printed to stderr |
|||
* |
|||
* int gamemode_query_status() - Query the current status of gamemode |
|||
* 0 if gamemode is inactive |
|||
* 1 if gamemode is active |
|||
* 2 if gamemode is active and this client is registered |
|||
* -1 if the query failed |
|||
* |
|||
* int gamemode_request_start_for(pid_t pid) - Request gamemode starts for another process |
|||
* 0 if the request was sent successfully |
|||
* -1 if the request failed |
|||
* -2 if the request was rejected |
|||
* |
|||
* int gamemode_request_end_for(pid_t pid) - Request gamemode ends for another process |
|||
* 0 if the request was sent successfully |
|||
* -1 if the request failed |
|||
* -2 if the request was rejected |
|||
* |
|||
* int gamemode_query_status_for(pid_t pid) - Query status of gamemode for another process |
|||
* 0 if gamemode is inactive |
|||
* 1 if gamemode is active |
|||
* 2 if gamemode is active and this client is registered |
|||
* -1 if the query failed |
|||
* |
|||
* const char* gamemode_error_string() - Get an error string |
|||
* returns a string describing any of the above errors |
|||
* |
|||
* Note: All the above requests can be blocking - dbus requests can and will block while the daemon |
|||
* handles the request. It is not recommended to make these calls in performance critical code |
|||
*/ |
|||
|
|||
#include <stdbool.h> |
|||
#include <stdio.h> |
|||
|
|||
#include <dlfcn.h> |
|||
#include <string.h> |
|||
|
|||
#include <assert.h> |
|||
|
|||
#include <sys/types.h> |
|||
|
|||
static char internal_gamemode_client_error_string[512] = { 0 }; |
|||
|
|||
/** |
|||
* Load libgamemode dynamically to dislodge us from most dependencies. |
|||
* This allows clients to link and/or use this regardless of runtime. |
|||
* See SDL2 for an example of the reasoning behind this in terms of |
|||
* dynamic versioning as well. |
|||
*/ |
|||
static volatile int internal_libgamemode_loaded = 1; |
|||
|
|||
/* Typedefs for the functions to load */ |
|||
typedef int (*api_call_return_int)(void); |
|||
typedef const char *(*api_call_return_cstring)(void); |
|||
typedef int (*api_call_pid_return_int)(pid_t); |
|||
|
|||
/* Storage for functors */ |
|||
static api_call_return_int REAL_internal_gamemode_request_start = NULL; |
|||
static api_call_return_int REAL_internal_gamemode_request_end = NULL; |
|||
static api_call_return_int REAL_internal_gamemode_query_status = NULL; |
|||
static api_call_return_cstring REAL_internal_gamemode_error_string = NULL; |
|||
static api_call_pid_return_int REAL_internal_gamemode_request_start_for = NULL; |
|||
static api_call_pid_return_int REAL_internal_gamemode_request_end_for = NULL; |
|||
static api_call_pid_return_int REAL_internal_gamemode_query_status_for = NULL; |
|||
|
|||
/** |
|||
* Internal helper to perform the symbol binding safely. |
|||
* |
|||
* Returns 0 on success and -1 on failure |
|||
*/ |
|||
__attribute__((always_inline)) static inline int internal_bind_libgamemode_symbol( |
|||
void *handle, const char *name, void **out_func, size_t func_size, bool required) |
|||
{ |
|||
void *symbol_lookup = NULL; |
|||
char *dl_error = NULL; |
|||
|
|||
/* Safely look up the symbol */ |
|||
symbol_lookup = dlsym(handle, name); |
|||
dl_error = dlerror(); |
|||
if (required && (dl_error || !symbol_lookup)) { |
|||
snprintf(internal_gamemode_client_error_string, |
|||
sizeof(internal_gamemode_client_error_string), |
|||
"dlsym failed - %s", |
|||
dl_error); |
|||
return -1; |
|||
} |
|||
|
|||
/* Have the symbol correctly, copy it to make it usable */ |
|||
memcpy(out_func, &symbol_lookup, func_size); |
|||
return 0; |
|||
} |
|||
|
|||
/** |
|||
* Loads libgamemode and needed functions |
|||
* |
|||
* Returns 0 on success and -1 on failure |
|||
*/ |
|||
__attribute__((always_inline)) static inline int internal_load_libgamemode(void) |
|||
{ |
|||
/* We start at 1, 0 is a success and -1 is a fail */ |
|||
if (internal_libgamemode_loaded != 1) { |
|||
return internal_libgamemode_loaded; |
|||
} |
|||
|
|||
/* Anonymous struct type to define our bindings */ |
|||
struct binding { |
|||
const char *name; |
|||
void **functor; |
|||
size_t func_size; |
|||
bool required; |
|||
} bindings[] = { |
|||
{ "real_gamemode_request_start", |
|||
(void **)&REAL_internal_gamemode_request_start, |
|||
sizeof(REAL_internal_gamemode_request_start), |
|||
true }, |
|||
{ "real_gamemode_request_end", |
|||
(void **)&REAL_internal_gamemode_request_end, |
|||
sizeof(REAL_internal_gamemode_request_end), |
|||
true }, |
|||
{ "real_gamemode_query_status", |
|||
(void **)&REAL_internal_gamemode_query_status, |
|||
sizeof(REAL_internal_gamemode_query_status), |
|||
false }, |
|||
{ "real_gamemode_error_string", |
|||
(void **)&REAL_internal_gamemode_error_string, |
|||
sizeof(REAL_internal_gamemode_error_string), |
|||
true }, |
|||
{ "real_gamemode_request_start_for", |
|||
(void **)&REAL_internal_gamemode_request_start_for, |
|||
sizeof(REAL_internal_gamemode_request_start_for), |
|||
false }, |
|||
{ "real_gamemode_request_end_for", |
|||
(void **)&REAL_internal_gamemode_request_end_for, |
|||
sizeof(REAL_internal_gamemode_request_end_for), |
|||
false }, |
|||
{ "real_gamemode_query_status_for", |
|||
(void **)&REAL_internal_gamemode_query_status_for, |
|||
sizeof(REAL_internal_gamemode_query_status_for), |
|||
false }, |
|||
}; |
|||
|
|||
void *libgamemode = NULL; |
|||
|
|||
/* Try and load libgamemode */ |
|||
libgamemode = dlopen("libgamemode.so.0", RTLD_NOW); |
|||
if (!libgamemode) { |
|||
/* Attempt to load unversioned library for compatibility with older |
|||
* versions (as of writing, there are no ABI changes between the two - |
|||
* this may need to change if ever ABI-breaking changes are made) */ |
|||
libgamemode = dlopen("libgamemode.so", RTLD_NOW); |
|||
if (!libgamemode) { |
|||
snprintf(internal_gamemode_client_error_string, |
|||
sizeof(internal_gamemode_client_error_string), |
|||
"dlopen failed - %s", |
|||
dlerror()); |
|||
internal_libgamemode_loaded = -1; |
|||
return -1; |
|||
} |
|||
} |
|||
|
|||
/* Attempt to bind all symbols */ |
|||
for (size_t i = 0; i < sizeof(bindings) / sizeof(bindings[0]); i++) { |
|||
struct binding *binder = &bindings[i]; |
|||
|
|||
if (internal_bind_libgamemode_symbol(libgamemode, |
|||
binder->name, |
|||
binder->functor, |
|||
binder->func_size, |
|||
binder->required)) { |
|||
internal_libgamemode_loaded = -1; |
|||
return -1; |
|||
}; |
|||
} |
|||
|
|||
/* Success */ |
|||
internal_libgamemode_loaded = 0; |
|||
return 0; |
|||
} |
|||
|
|||
/** |
|||
* Redirect to the real libgamemode |
|||
*/ |
|||
__attribute__((always_inline)) static inline const char *gamemode_error_string(void) |
|||
{ |
|||
/* If we fail to load the system gamemode, or we have an error string already, return our error |
|||
* string instead of diverting to the system version */ |
|||
if (internal_load_libgamemode() < 0 || internal_gamemode_client_error_string[0] != '\0') { |
|||
return internal_gamemode_client_error_string; |
|||
} |
|||
|
|||
/* Assert for static analyser that the function is not NULL */ |
|||
assert(REAL_internal_gamemode_error_string != NULL); |
|||
|
|||
return REAL_internal_gamemode_error_string(); |
|||
} |
|||
|
|||
/** |
|||
* Redirect to the real libgamemode |
|||
* Allow automatically requesting game mode |
|||
* Also prints errors as they happen. |
|||
*/ |
|||
#ifdef GAMEMODE_AUTO |
|||
__attribute__((constructor)) |
|||
#else |
|||
__attribute__((always_inline)) static inline |
|||
#endif |
|||
int gamemode_request_start(void) |
|||
{ |
|||
/* Need to load gamemode */ |
|||
if (internal_load_libgamemode() < 0) { |
|||
#ifdef GAMEMODE_AUTO |
|||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); |
|||
#endif |
|||
return -1; |
|||
} |
|||
|
|||
/* Assert for static analyser that the function is not NULL */ |
|||
assert(REAL_internal_gamemode_request_start != NULL); |
|||
|
|||
if (REAL_internal_gamemode_request_start() < 0) { |
|||
#ifdef GAMEMODE_AUTO |
|||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); |
|||
#endif |
|||
return -1; |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
/* Redirect to the real libgamemode */ |
|||
#ifdef GAMEMODE_AUTO |
|||
__attribute__((destructor)) |
|||
#else |
|||
__attribute__((always_inline)) static inline |
|||
#endif |
|||
int gamemode_request_end(void) |
|||
{ |
|||
/* Need to load gamemode */ |
|||
if (internal_load_libgamemode() < 0) { |
|||
#ifdef GAMEMODE_AUTO |
|||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); |
|||
#endif |
|||
return -1; |
|||
} |
|||
|
|||
/* Assert for static analyser that the function is not NULL */ |
|||
assert(REAL_internal_gamemode_request_end != NULL); |
|||
|
|||
if (REAL_internal_gamemode_request_end() < 0) { |
|||
#ifdef GAMEMODE_AUTO |
|||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); |
|||
#endif |
|||
return -1; |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
/* Redirect to the real libgamemode */ |
|||
__attribute__((always_inline)) static inline int gamemode_query_status(void) |
|||
{ |
|||
/* Need to load gamemode */ |
|||
if (internal_load_libgamemode() < 0) { |
|||
return -1; |
|||
} |
|||
|
|||
if (REAL_internal_gamemode_query_status == NULL) { |
|||
snprintf(internal_gamemode_client_error_string, |
|||
sizeof(internal_gamemode_client_error_string), |
|||
"gamemode_query_status missing (older host?)"); |
|||
return -1; |
|||
} |
|||
|
|||
return REAL_internal_gamemode_query_status(); |
|||
} |
|||
|
|||
/* Redirect to the real libgamemode */ |
|||
__attribute__((always_inline)) static inline int gamemode_request_start_for(pid_t pid) |
|||
{ |
|||
/* Need to load gamemode */ |
|||
if (internal_load_libgamemode() < 0) { |
|||
return -1; |
|||
} |
|||
|
|||
if (REAL_internal_gamemode_request_start_for == NULL) { |
|||
snprintf(internal_gamemode_client_error_string, |
|||
sizeof(internal_gamemode_client_error_string), |
|||
"gamemode_request_start_for missing (older host?)"); |
|||
return -1; |
|||
} |
|||
|
|||
return REAL_internal_gamemode_request_start_for(pid); |
|||
} |
|||
|
|||
/* Redirect to the real libgamemode */ |
|||
__attribute__((always_inline)) static inline int gamemode_request_end_for(pid_t pid) |
|||
{ |
|||
/* Need to load gamemode */ |
|||
if (internal_load_libgamemode() < 0) { |
|||
return -1; |
|||
} |
|||
|
|||
if (REAL_internal_gamemode_request_end_for == NULL) { |
|||
snprintf(internal_gamemode_client_error_string, |
|||
sizeof(internal_gamemode_client_error_string), |
|||
"gamemode_request_end_for missing (older host?)"); |
|||
return -1; |
|||
} |
|||
|
|||
return REAL_internal_gamemode_request_end_for(pid); |
|||
} |
|||
|
|||
/* Redirect to the real libgamemode */ |
|||
__attribute__((always_inline)) static inline int gamemode_query_status_for(pid_t pid) |
|||
{ |
|||
/* Need to load gamemode */ |
|||
if (internal_load_libgamemode() < 0) { |
|||
return -1; |
|||
} |
|||
|
|||
if (REAL_internal_gamemode_query_status_for == NULL) { |
|||
snprintf(internal_gamemode_client_error_string, |
|||
sizeof(internal_gamemode_client_error_string), |
|||
"gamemode_query_status_for missing (older host?)"); |
|||
return -1; |
|||
} |
|||
|
|||
return REAL_internal_gamemode_query_status_for(pid); |
|||
} |
|||
|
|||
#endif // CLIENT_GAMEMODE_H |
|||
@ -1,40 +0,0 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include <gamemode_client.h>
|
|||
|
|||
#include "common/linux/gamemode.h"
|
|||
#include "common/logging/log.h"
|
|||
#include "common/settings.h"
|
|||
|
|||
namespace Common::Linux { |
|||
|
|||
void StartGamemode() { |
|||
if (Settings::values.enable_gamemode) { |
|||
if (gamemode_request_start() < 0) { |
|||
LOG_WARNING(Frontend, "Failed to start gamemode: {}", gamemode_error_string()); |
|||
} else { |
|||
LOG_INFO(Frontend, "Started gamemode"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void StopGamemode() { |
|||
if (Settings::values.enable_gamemode) { |
|||
if (gamemode_request_end() < 0) { |
|||
LOG_WARNING(Frontend, "Failed to stop gamemode: {}", gamemode_error_string()); |
|||
} else { |
|||
LOG_INFO(Frontend, "Stopped gamemode"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void SetGamemodeState(bool state) { |
|||
if (state) { |
|||
StartGamemode(); |
|||
} else { |
|||
StopGamemode(); |
|||
} |
|||
} |
|||
|
|||
} // namespace Common::Linux
|
|||
@ -1,24 +0,0 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
namespace Common::Linux { |
|||
|
|||
/** |
|||
* Start the (Feral Interactive) Linux gamemode if it is installed and it is activated |
|||
*/ |
|||
void StartGamemode(); |
|||
|
|||
/** |
|||
* Stop the (Feral Interactive) Linux gamemode if it is installed and it is activated |
|||
*/ |
|||
void StopGamemode(); |
|||
|
|||
/** |
|||
* Start or stop the (Feral Interactive) Linux gamemode if it is installed and it is activated |
|||
* @param state The new state the gamemode should have |
|||
*/ |
|||
void SetGamemodeState(bool state); |
|||
|
|||
} // namespace Common::Linux |
|||
@ -0,0 +1,52 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
// While technically available on al *NIX platforms, Linux is only available
|
|||
// as the primary target of libgamemode.so - so warnings are suppressed
|
|||
#ifdef __unix__
|
|||
#include <gamemode_client.h>
|
|||
#endif
|
|||
#include "qt_common/gamemode.h"
|
|||
#include "common/logging/log.h"
|
|||
#include "qt_common/config/uisettings.h"
|
|||
|
|||
namespace Common::FeralGamemode { |
|||
|
|||
/// @brief Start the gamemode client
|
|||
void Start() noexcept { |
|||
if (UISettings::values.enable_gamemode) { |
|||
#ifdef __unix__
|
|||
if (gamemode_request_start() < 0) { |
|||
#ifdef __linux__
|
|||
LOG_WARNING(Frontend, "{}", gamemode_error_string()); |
|||
#else
|
|||
LOG_INFO(Frontend, "{}", gamemode_error_string()); |
|||
#endif
|
|||
} else { |
|||
LOG_INFO(Frontend, "Done"); |
|||
} |
|||
#endif
|
|||
} |
|||
} |
|||
|
|||
/// @brief Stop the gmemode client
|
|||
void Stop() noexcept { |
|||
if (UISettings::values.enable_gamemode) { |
|||
#ifdef __unix__
|
|||
if (gamemode_request_end() < 0) { |
|||
#ifdef __linux__
|
|||
LOG_WARNING(Frontend, "{}", gamemode_error_string()); |
|||
#else
|
|||
LOG_INFO(Frontend, "{}", gamemode_error_string()); |
|||
#endif
|
|||
} else { |
|||
LOG_INFO(Frontend, "Done"); |
|||
} |
|||
#endif
|
|||
} |
|||
} |
|||
|
|||
} // namespace Common::Linux
|
|||
@ -0,0 +1,14 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
namespace Common::FeralGamemode { |
|||
|
|||
void Start() noexcept; |
|||
void Stop() noexcept; |
|||
|
|||
} // namespace Common::FeralGamemode |
|||
@ -1,75 +0,0 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "common/settings.h"
|
|||
#include "core/core.h"
|
|||
#include "ui_configure_linux_tab.h"
|
|||
#include "yuzu/configuration/configuration_shared.h"
|
|||
#include "yuzu/configuration/configure_linux_tab.h"
|
|||
#include "yuzu/configuration/shared_widget.h"
|
|||
|
|||
ConfigureLinuxTab::ConfigureLinuxTab(const Core::System& system_, |
|||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_, |
|||
const ConfigurationShared::Builder& builder, QWidget* parent) |
|||
: Tab(group_, parent), ui(std::make_unique<Ui::ConfigureLinuxTab>()), system{system_} { |
|||
ui->setupUi(this); |
|||
|
|||
Setup(builder); |
|||
|
|||
SetConfiguration(); |
|||
} |
|||
|
|||
ConfigureLinuxTab::~ConfigureLinuxTab() = default; |
|||
|
|||
void ConfigureLinuxTab::SetConfiguration() {} |
|||
void ConfigureLinuxTab::Setup(const ConfigurationShared::Builder& builder) { |
|||
QLayout& linux_layout = *ui->linux_widget->layout(); |
|||
|
|||
std::map<u32, QWidget*> linux_hold{}; |
|||
|
|||
std::vector<Settings::BasicSetting*> settings; |
|||
const auto push = [&](Settings::Category category) { |
|||
for (const auto setting : Settings::values.linkage.by_category[category]) { |
|||
settings.push_back(setting); |
|||
} |
|||
}; |
|||
|
|||
push(Settings::Category::Linux); |
|||
|
|||
for (auto* setting : settings) { |
|||
auto* widget = builder.BuildWidget(setting, apply_funcs); |
|||
|
|||
if (widget == nullptr) { |
|||
continue; |
|||
} |
|||
if (!widget->Valid()) { |
|||
widget->deleteLater(); |
|||
continue; |
|||
} |
|||
|
|||
linux_hold.insert({setting->Id(), widget}); |
|||
} |
|||
|
|||
for (const auto& [id, widget] : linux_hold) { |
|||
linux_layout.addWidget(widget); |
|||
} |
|||
} |
|||
|
|||
void ConfigureLinuxTab::ApplyConfiguration() { |
|||
const bool is_powered_on = system.IsPoweredOn(); |
|||
for (const auto& apply_func : apply_funcs) { |
|||
apply_func(is_powered_on); |
|||
} |
|||
} |
|||
|
|||
void ConfigureLinuxTab::changeEvent(QEvent* event) { |
|||
if (event->type() == QEvent::LanguageChange) { |
|||
RetranslateUI(); |
|||
} |
|||
|
|||
QWidget::changeEvent(event); |
|||
} |
|||
|
|||
void ConfigureLinuxTab::RetranslateUI() { |
|||
ui->retranslateUi(this); |
|||
} |
|||
@ -1,44 +0,0 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <QWidget> |
|||
|
|||
namespace Core { |
|||
class System; |
|||
} |
|||
|
|||
namespace Ui { |
|||
class ConfigureLinuxTab; |
|||
} |
|||
|
|||
namespace ConfigurationShared { |
|||
class Builder; |
|||
} |
|||
|
|||
class ConfigureLinuxTab : public ConfigurationShared::Tab { |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
explicit ConfigureLinuxTab(const Core::System& system_, |
|||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, |
|||
const ConfigurationShared::Builder& builder, |
|||
QWidget* parent = nullptr); |
|||
~ConfigureLinuxTab() override; |
|||
|
|||
void ApplyConfiguration() override; |
|||
void SetConfiguration() override; |
|||
|
|||
private: |
|||
void changeEvent(QEvent* event) override; |
|||
void RetranslateUI(); |
|||
|
|||
void Setup(const ConfigurationShared::Builder& builder); |
|||
|
|||
std::unique_ptr<Ui::ConfigureLinuxTab> ui; |
|||
|
|||
const Core::System& system; |
|||
|
|||
std::vector<std::function<void(bool)>> apply_funcs{}; |
|||
}; |
|||
@ -1,53 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<ui version="4.0"> |
|||
<class>ConfigureLinuxTab</class> |
|||
<widget class="QWidget" name="ConfigureLinuxTab"> |
|||
<property name="accessibleName"> |
|||
<string>Linux</string> |
|||
</property> |
|||
<layout class="QVBoxLayout"> |
|||
<item> |
|||
<widget class="QGroupBox" name="LinuxGroupBox"> |
|||
<property name="title"> |
|||
<string>Linux</string> |
|||
</property> |
|||
<layout class="QVBoxLayout" name="LinuxVerticalLayout_1"> |
|||
<item> |
|||
<widget class="QWidget" name="linux_widget" native="true"> |
|||
<layout class="QVBoxLayout" name="LinuxVerticalLayout_2"> |
|||
<property name="leftMargin"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="topMargin"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="rightMargin"> |
|||
<number>0</number> |
|||
</property> |
|||
<property name="bottomMargin"> |
|||
<number>0</number> |
|||
</property> |
|||
</layout> |
|||
</widget> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
</item> |
|||
<item> |
|||
<spacer name="verticalSpacer"> |
|||
<property name="orientation"> |
|||
<enum>Qt::Vertical</enum> |
|||
</property> |
|||
<property name="sizeHint" stdset="0"> |
|||
<size> |
|||
<width>20</width> |
|||
<height>40</height> |
|||
</size> |
|||
</property> |
|||
</spacer> |
|||
</item> |
|||
</layout> |
|||
</widget> |
|||
<resources/> |
|||
<connections/> |
|||
</ui> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue