mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2024-11-22 09:49:14 +01:00
Corrected overzealous removal of SDL2 frontend
This commit is contained in:
parent
48adc58f88
commit
91294919bb
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -52,6 +52,9 @@
|
||||
[submodule "libyuv"]
|
||||
path = externals/libyuv
|
||||
url = https://github.com/lemenkov/libyuv.git
|
||||
[submodule "sdl2"]
|
||||
path = externals/sdl2/SDL
|
||||
url = https://github.com/libsdl-org/SDL
|
||||
[submodule "cryptopp-cmake"]
|
||||
path = externals/cryptopp-cmake
|
||||
url = https://github.com/abdes/cryptopp-cmake.git
|
||||
|
@ -56,6 +56,9 @@ else()
|
||||
set(DEFAULT_ENABLE_LTO OFF)
|
||||
endif()
|
||||
|
||||
option(ENABLE_SDL2 "Enable using SDL2" ON)
|
||||
option(USE_SYSTEM_SDL2 "Use the system SDL2 lib (instead of the bundled one)" OFF)
|
||||
|
||||
# Set bundled qt as dependent options.
|
||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
|
||||
@ -393,6 +396,15 @@ if (NOT USE_SYSTEM_BOOST)
|
||||
add_library(Boost::iostreams ALIAS boost_iostreams)
|
||||
endif()
|
||||
|
||||
# SDL2
|
||||
if (ENABLE_SDL2 AND USE_SYSTEM_SDL2)
|
||||
find_package(SDL2 REQUIRED)
|
||||
add_library(SDL2 INTERFACE)
|
||||
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}")
|
||||
target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}")
|
||||
add_library(SDL2::SDL2 ALIAS SDL2)
|
||||
endif()
|
||||
|
||||
if (ENABLE_LIBUSB AND USE_SYSTEM_LIBUSB)
|
||||
include(FindPkgConfig)
|
||||
find_package(LibUSB)
|
||||
|
8
externals/CMakeLists.txt
vendored
8
externals/CMakeLists.txt
vendored
@ -183,6 +183,14 @@ endif()
|
||||
# Teakra
|
||||
add_subdirectory(teakra EXCLUDE_FROM_ALL)
|
||||
|
||||
# SDL2
|
||||
if (ENABLE_SDL2 AND NOT USE_SYSTEM_SDL2)
|
||||
if (MSVC)
|
||||
set (SDL_LIBC ON)
|
||||
endif()
|
||||
add_subdirectory(sdl2)
|
||||
endif()
|
||||
|
||||
# libusb
|
||||
if (ENABLE_LIBUSB AND NOT USE_SYSTEM_LIBUSB)
|
||||
add_subdirectory(libusb)
|
||||
|
25
externals/sdl2/CMakeLists.txt
vendored
Normal file
25
externals/sdl2/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# Configure static library build
|
||||
set(SDL_SHARED OFF CACHE BOOL "")
|
||||
set(SDL_STATIC ON CACHE BOOL "")
|
||||
|
||||
# Subsystems
|
||||
set(SDL_ATOMIC ON CACHE BOOL "")
|
||||
set(SDL_AUDIO ON CACHE BOOL "")
|
||||
set(SDL_VIDEO ON CACHE BOOL "")
|
||||
set(SDL_RENDER OFF CACHE BOOL "")
|
||||
set(SDL_EVENTS ON CACHE BOOL "")
|
||||
set(SDL_JOYSTICK ON CACHE BOOL "")
|
||||
set(SDL_HAPTIC OFF CACHE BOOL "")
|
||||
set(SDL_HIDAPI ON CACHE BOOL "")
|
||||
set(SDL_POWER OFF CACHE BOOL "")
|
||||
set(SDL_THREADS ON CACHE BOOL "")
|
||||
set(SDL_TIMERS ON CACHE BOOL "")
|
||||
set(SDL_FILE ON CACHE BOOL "")
|
||||
set(SDL_LOADSO ON CACHE BOOL "")
|
||||
set(SDL_CPUINFO ON CACHE BOOL "")
|
||||
set(SDL_FILESYSTEM OFF CACHE BOOL "")
|
||||
set(SDL_DLOPEN ON CACHE BOOL "")
|
||||
set(SDL_SENSOR OFF CACHE BOOL "")
|
||||
set(SDL_LOCALE OFF CACHE BOOL "")
|
||||
|
||||
add_subdirectory(SDL)
|
1
externals/sdl2/SDL
vendored
Submodule
1
externals/sdl2/SDL
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit ba2f78a0069118a6c583f1fbf1420144ffa35bad
|
@ -13,6 +13,7 @@
|
||||
#include "common/math_util.h"
|
||||
#include "common/param_package.h"
|
||||
#include "input_common/main.h"
|
||||
#include "input_common/sdl/sdl.h"
|
||||
#include "jni/input_manager.h"
|
||||
#include "jni/ndk_motion.h"
|
||||
|
||||
|
@ -36,6 +36,7 @@ add_library(audio_core STATIC
|
||||
time_stretch.cpp
|
||||
time_stretch.h
|
||||
|
||||
$<$<BOOL:${ENABLE_SDL2}>:sdl2_sink.cpp sdl2_sink.h>
|
||||
$<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h cubeb_input.cpp cubeb_input.h>
|
||||
$<$<BOOL:${ENABLE_OPENAL}>:openal_input.cpp openal_input.h openal_sink.cpp openal_sink.h>
|
||||
)
|
||||
@ -45,6 +46,11 @@ create_target_directory_groups(audio_core)
|
||||
target_link_libraries(audio_core PUBLIC lime_common lime_core)
|
||||
target_link_libraries(audio_core PRIVATE faad2 SoundTouch teakra)
|
||||
|
||||
if(ENABLE_SDL2)
|
||||
target_link_libraries(audio_core PRIVATE SDL2::SDL2)
|
||||
target_compile_definitions(audio_core PRIVATE HAVE_SDL2)
|
||||
endif()
|
||||
|
||||
if(ENABLE_CUBEB)
|
||||
target_link_libraries(audio_core PRIVATE cubeb)
|
||||
target_compile_definitions(audio_core PUBLIC HAVE_CUBEB)
|
||||
|
108
src/audio_core/sdl2_sink.cpp
Normal file
108
src/audio_core/sdl2_sink.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <SDL.h>
|
||||
#include "audio_core/audio_types.h"
|
||||
#include "audio_core/sdl2_sink.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
struct SDL2Sink::Impl {
|
||||
unsigned int sample_rate = 0;
|
||||
|
||||
SDL_AudioDeviceID audio_device_id = 0;
|
||||
|
||||
std::function<void(s16*, std::size_t)> cb;
|
||||
|
||||
static void Callback(void* impl_, u8* buffer, int buffer_size_in_bytes);
|
||||
};
|
||||
|
||||
SDL2Sink::SDL2Sink(std::string device_name) : impl(std::make_unique<Impl>()) {
|
||||
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
|
||||
LOG_CRITICAL(Audio_Sink, "SDL_Init(SDL_INIT_AUDIO) failed with: {}", SDL_GetError());
|
||||
impl->audio_device_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_AudioSpec desired_audiospec;
|
||||
SDL_zero(desired_audiospec);
|
||||
desired_audiospec.format = AUDIO_S16;
|
||||
desired_audiospec.channels = 2;
|
||||
desired_audiospec.freq = native_sample_rate;
|
||||
desired_audiospec.samples = 512;
|
||||
desired_audiospec.userdata = impl.get();
|
||||
desired_audiospec.callback = &Impl::Callback;
|
||||
|
||||
SDL_AudioSpec obtained_audiospec;
|
||||
SDL_zero(obtained_audiospec);
|
||||
|
||||
const char* device = nullptr;
|
||||
if (device_name != auto_device_name && !device_name.empty()) {
|
||||
device = device_name.c_str();
|
||||
}
|
||||
|
||||
impl->audio_device_id =
|
||||
SDL_OpenAudioDevice(device, false, &desired_audiospec, &obtained_audiospec, 0);
|
||||
if (impl->audio_device_id <= 0) {
|
||||
LOG_CRITICAL(Audio_Sink, "SDL_OpenAudioDevice failed with code {} for device \"{}\"",
|
||||
impl->audio_device_id, device_name);
|
||||
return;
|
||||
}
|
||||
|
||||
impl->sample_rate = obtained_audiospec.freq;
|
||||
|
||||
// SDL2 audio devices start out paused, unpause it:
|
||||
SDL_PauseAudioDevice(impl->audio_device_id, 0);
|
||||
}
|
||||
|
||||
SDL2Sink::~SDL2Sink() {
|
||||
if (impl->audio_device_id <= 0)
|
||||
return;
|
||||
|
||||
SDL_CloseAudioDevice(impl->audio_device_id);
|
||||
}
|
||||
|
||||
unsigned int SDL2Sink::GetNativeSampleRate() const {
|
||||
if (impl->audio_device_id <= 0)
|
||||
return native_sample_rate;
|
||||
|
||||
return impl->sample_rate;
|
||||
}
|
||||
|
||||
void SDL2Sink::SetCallback(std::function<void(s16*, std::size_t)> cb) {
|
||||
impl->cb = cb;
|
||||
}
|
||||
|
||||
void SDL2Sink::Impl::Callback(void* impl_, u8* buffer, int buffer_size_in_bytes) {
|
||||
Impl* impl = reinterpret_cast<Impl*>(impl_);
|
||||
if (!impl || !impl->cb)
|
||||
return;
|
||||
|
||||
const std::size_t num_frames = buffer_size_in_bytes / (2 * sizeof(s16));
|
||||
|
||||
impl->cb(reinterpret_cast<s16*>(buffer), num_frames);
|
||||
}
|
||||
|
||||
std::vector<std::string> ListSDL2SinkDevices() {
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
|
||||
LOG_CRITICAL(Audio_Sink, "SDL_InitSubSystem failed with: {}", SDL_GetError());
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> device_list;
|
||||
const int device_count = SDL_GetNumAudioDevices(0);
|
||||
for (int i = 0; i < device_count; ++i) {
|
||||
device_list.push_back(SDL_GetAudioDeviceName(i, 0));
|
||||
}
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
|
||||
return device_list;
|
||||
}
|
||||
|
||||
} // namespace AudioCore
|
29
src/audio_core/sdl2_sink.h
Normal file
29
src/audio_core/sdl2_sink.h
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include "audio_core/sink.h"
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
class SDL2Sink final : public Sink {
|
||||
public:
|
||||
explicit SDL2Sink(std::string device_id);
|
||||
~SDL2Sink() override;
|
||||
|
||||
unsigned int GetNativeSampleRate() const override;
|
||||
|
||||
void SetCallback(std::function<void(s16*, std::size_t)> cb) override;
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
std::vector<std::string> ListSDL2SinkDevices();
|
||||
|
||||
} // namespace AudioCore
|
@ -8,6 +8,9 @@
|
||||
#include <vector>
|
||||
#include "audio_core/null_sink.h"
|
||||
#include "audio_core/sink_details.h"
|
||||
#ifdef HAVE_SDL2
|
||||
#include "audio_core/sdl2_sink.h"
|
||||
#endif
|
||||
#ifdef HAVE_CUBEB
|
||||
#include "audio_core/cubeb_sink.h"
|
||||
#endif
|
||||
@ -33,6 +36,13 @@ constexpr std::array sink_details = {
|
||||
return std::make_unique<OpenALSink>(std::string(device_id));
|
||||
},
|
||||
&ListOpenALSinkDevices},
|
||||
#endif
|
||||
#ifdef HAVE_SDL2
|
||||
SinkDetails{SinkType::SDL2, "SDL2",
|
||||
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
||||
return std::make_unique<SDL2Sink>(std::string(device_id));
|
||||
},
|
||||
&ListSDL2SinkDevices},
|
||||
#endif
|
||||
SinkDetails{SinkType::Null, "None",
|
||||
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
||||
|
@ -10,6 +10,8 @@ add_library(input_common STATIC
|
||||
precompiled_headers.h
|
||||
touch_from_button.cpp
|
||||
touch_from_button.h
|
||||
sdl/sdl.cpp
|
||||
sdl/sdl.h
|
||||
udp/client.cpp
|
||||
udp/client.h
|
||||
udp/protocol.cpp
|
||||
@ -18,6 +20,15 @@ add_library(input_common STATIC
|
||||
udp/udp.h
|
||||
)
|
||||
|
||||
if(ENABLE_SDL2)
|
||||
target_sources(input_common PRIVATE
|
||||
sdl/sdl_impl.cpp
|
||||
sdl/sdl_impl.h
|
||||
)
|
||||
target_link_libraries(input_common PRIVATE SDL2::SDL2)
|
||||
target_compile_definitions(input_common PRIVATE HAVE_SDL2)
|
||||
endif()
|
||||
|
||||
if(ENABLE_LIBUSB)
|
||||
target_sources(input_common PRIVATE
|
||||
gcadapter/gc_adapter.cpp
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "input_common/keyboard.h"
|
||||
#include "input_common/main.h"
|
||||
#include "input_common/motion_emu.h"
|
||||
#include "input_common/sdl/sdl.h"
|
||||
#include "input_common/sdl/sdl_impl.h"
|
||||
#include "input_common/touch_from_button.h"
|
||||
#include "input_common/udp/udp.h"
|
||||
|
||||
@ -26,6 +28,7 @@ std::shared_ptr<GCAdapter::Adapter> gcadapter;
|
||||
static std::shared_ptr<Keyboard> keyboard;
|
||||
static std::shared_ptr<MotionEmu> motion_emu;
|
||||
static std::unique_ptr<CemuhookUDP::State> udp;
|
||||
static std::unique_ptr<SDL::State> sdl;
|
||||
|
||||
void Init() {
|
||||
#ifdef ENABLE_GCADAPTER
|
||||
@ -44,6 +47,8 @@ void Init() {
|
||||
Input::RegisterFactory<Input::TouchDevice>("touch_from_button",
|
||||
std::make_shared<TouchFromButtonFactory>());
|
||||
|
||||
sdl = SDL::Init();
|
||||
|
||||
udp = CemuhookUDP::Init();
|
||||
}
|
||||
|
||||
@ -61,6 +66,7 @@ void Shutdown() {
|
||||
motion_emu.reset();
|
||||
Input::UnregisterFactory<Input::TouchDevice>("emu_window");
|
||||
Input::UnregisterFactory<Input::TouchDevice>("touch_from_button");
|
||||
sdl.reset();
|
||||
udp.reset();
|
||||
}
|
||||
|
||||
@ -97,6 +103,10 @@ std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left,
|
||||
Common::ParamPackage GetControllerButtonBinds(const Common::ParamPackage& params, int button) {
|
||||
const auto native_button{static_cast<Settings::NativeButton::Values>(button)};
|
||||
const auto engine{params.Get("engine", "")};
|
||||
if (engine == "sdl") {
|
||||
return dynamic_cast<SDL::SDLState*>(sdl.get())->GetSDLControllerButtonBindByGUID(
|
||||
params.Get("guid", "0"), params.Get("port", 0), native_button);
|
||||
}
|
||||
#ifdef ENABLE_GCADAPTER
|
||||
if (engine == "gcpad") {
|
||||
return gcbuttons->GetGcTo3DSMappedButton(params.Get("port", 0), native_button);
|
||||
@ -108,6 +118,10 @@ Common::ParamPackage GetControllerButtonBinds(const Common::ParamPackage& params
|
||||
Common::ParamPackage GetControllerAnalogBinds(const Common::ParamPackage& params, int analog) {
|
||||
const auto native_analog{static_cast<Settings::NativeAnalog::Values>(analog)};
|
||||
const auto engine{params.Get("engine", "")};
|
||||
if (engine == "sdl") {
|
||||
return dynamic_cast<SDL::SDLState*>(sdl.get())->GetSDLControllerAnalogBindByGUID(
|
||||
params.Get("guid", "0"), params.Get("port", 0), native_analog);
|
||||
}
|
||||
#ifdef ENABLE_GCADAPTER
|
||||
if (engine == "gcpad") {
|
||||
return gcanalog->GetGcTo3DSMappedAnalog(params.Get("port", 0), native_analog);
|
||||
@ -128,6 +142,9 @@ namespace Polling {
|
||||
std::vector<std::unique_ptr<DevicePoller>> GetPollers(DeviceType type) {
|
||||
std::vector<std::unique_ptr<DevicePoller>> pollers;
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
pollers = sdl->GetPollers(type);
|
||||
#endif
|
||||
#ifdef ENABLE_GCADAPTER
|
||||
switch (type) {
|
||||
case DeviceType::Analog:
|
||||
|
19
src/input_common/sdl/sdl.cpp
Normal file
19
src/input_common/sdl/sdl.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2018 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "input_common/sdl/sdl.h"
|
||||
#ifdef HAVE_SDL2
|
||||
#include "input_common/sdl/sdl_impl.h"
|
||||
#endif
|
||||
|
||||
namespace InputCommon::SDL {
|
||||
|
||||
std::unique_ptr<State> Init() {
|
||||
#ifdef HAVE_SDL2
|
||||
return std::make_unique<SDLState>();
|
||||
#else
|
||||
return std::make_unique<NullState>();
|
||||
#endif
|
||||
}
|
||||
} // namespace InputCommon::SDL
|
44
src/input_common/sdl/sdl.h
Normal file
44
src/input_common/sdl/sdl.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2018 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "core/frontend/input.h"
|
||||
#include "input_common/main.h"
|
||||
|
||||
union SDL_Event;
|
||||
|
||||
namespace Common {
|
||||
class ParamPackage;
|
||||
} // namespace Common
|
||||
|
||||
namespace InputCommon::Polling {
|
||||
class DevicePoller;
|
||||
enum class DeviceType;
|
||||
} // namespace InputCommon::Polling
|
||||
|
||||
namespace InputCommon::SDL {
|
||||
|
||||
class State {
|
||||
public:
|
||||
using Pollers = std::vector<std::unique_ptr<Polling::DevicePoller>>;
|
||||
|
||||
/// Unregisters SDL device factories and shut them down.
|
||||
virtual ~State() = default;
|
||||
|
||||
virtual Pollers GetPollers(Polling::DeviceType type) = 0;
|
||||
};
|
||||
|
||||
class NullState : public State {
|
||||
public:
|
||||
Pollers GetPollers(Polling::DeviceType type) override {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<State> Init();
|
||||
|
||||
} // namespace InputCommon::SDL
|
1092
src/input_common/sdl/sdl_impl.cpp
Normal file
1092
src/input_common/sdl/sdl_impl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
74
src/input_common/sdl/sdl_impl.h
Normal file
74
src/input_common/sdl/sdl_impl.h
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2018 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include "common/settings.h"
|
||||
#include "common/threadsafe_queue.h"
|
||||
#include "input_common/sdl/sdl.h"
|
||||
|
||||
union SDL_Event;
|
||||
using SDL_Joystick = struct _SDL_Joystick;
|
||||
using SDL_JoystickID = s32;
|
||||
using SDL_GameController = struct _SDL_GameController;
|
||||
|
||||
namespace InputCommon::SDL {
|
||||
|
||||
class SDLJoystick;
|
||||
class SDLGameController;
|
||||
class SDLButtonFactory;
|
||||
class SDLAnalogFactory;
|
||||
class SDLMotionFactory;
|
||||
|
||||
class SDLState : public State {
|
||||
public:
|
||||
/// Initializes and registers SDL device factories
|
||||
SDLState();
|
||||
|
||||
/// Unregisters SDL device factories and shut them down.
|
||||
~SDLState() override;
|
||||
|
||||
/// Handle SDL_Events for joysticks from SDL_PollEvent
|
||||
void HandleGameControllerEvent(const SDL_Event& event);
|
||||
|
||||
std::shared_ptr<SDLJoystick> GetSDLJoystickBySDLID(SDL_JoystickID sdl_id);
|
||||
std::shared_ptr<SDLJoystick> GetSDLJoystickByGUID(const std::string& guid, int port);
|
||||
|
||||
Common::ParamPackage GetSDLControllerButtonBindByGUID(const std::string& guid, int port,
|
||||
Settings::NativeButton::Values button);
|
||||
Common::ParamPackage GetSDLControllerAnalogBindByGUID(const std::string& guid, int port,
|
||||
Settings::NativeAnalog::Values analog);
|
||||
|
||||
/// Get all DevicePoller that use the SDL backend for a specific device type
|
||||
Pollers GetPollers(Polling::DeviceType type) override;
|
||||
|
||||
/// Used by the Pollers during config
|
||||
std::atomic<bool> polling = false;
|
||||
Common::SPSCQueue<SDL_Event> event_queue;
|
||||
|
||||
private:
|
||||
void InitJoystick(int joystick_index);
|
||||
void CloseJoystick(SDL_Joystick* sdl_joystick);
|
||||
|
||||
/// Needs to be called before SDL_QuitSubSystem.
|
||||
void CloseJoysticks();
|
||||
|
||||
/// Map of GUID of a list of corresponding virtual Joysticks
|
||||
std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map;
|
||||
std::mutex joystick_map_mutex;
|
||||
|
||||
std::shared_ptr<SDLButtonFactory> button_factory;
|
||||
std::shared_ptr<SDLAnalogFactory> analog_factory;
|
||||
std::shared_ptr<SDLMotionFactory> motion_factory;
|
||||
|
||||
bool start_thread = false;
|
||||
std::atomic<bool> initialized = false;
|
||||
|
||||
std::thread poll_thread;
|
||||
};
|
||||
} // namespace InputCommon::SDL
|
@ -119,6 +119,10 @@ __declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
constexpr int default_mouse_timeout = 2500;
|
||||
|
||||
/**
|
||||
@ -1129,9 +1133,58 @@ void GMainWindow::MigrateUserData() {
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
|
||||
#if defined(HAVE_SDL2) && defined(__unix__) && !defined(__APPLE__)
|
||||
static std::optional<QDBusObjectPath> HoldWakeLockLinux(u32 window_id = 0) {
|
||||
if (!QDBusConnection::sessionBus().isConnected()) {
|
||||
return {};
|
||||
}
|
||||
// reference: https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.Inhibit
|
||||
QDBusInterface xdp(QStringLiteral("org.freedesktop.portal.Desktop"),
|
||||
QStringLiteral("/org/freedesktop/portal/desktop"),
|
||||
QStringLiteral("org.freedesktop.portal.Inhibit"));
|
||||
if (!xdp.isValid()) {
|
||||
LOG_WARNING(Frontend, "Couldn't connect to XDP D-Bus endpoint");
|
||||
return {};
|
||||
}
|
||||
QVariantMap options = {};
|
||||
//: TRANSLATORS: This string is shown to the user to explain why Lime3DS needs to prevent the
|
||||
//: computer from sleeping
|
||||
options.insert(QString::fromLatin1("reason"),
|
||||
QCoreApplication::translate("GMainWindow", "Lime3DS is running a game"));
|
||||
// 0x4: Suspend lock; 0x8: Idle lock
|
||||
QDBusReply<QDBusObjectPath> reply =
|
||||
xdp.call(QString::fromLatin1("Inhibit"),
|
||||
QString::fromLatin1("x11:") + QString::number(window_id, 16), 12U, options);
|
||||
|
||||
if (reply.isValid()) {
|
||||
return reply.value();
|
||||
}
|
||||
LOG_WARNING(Frontend, "Couldn't read Inhibit reply from XDP: {}",
|
||||
reply.error().message().toStdString());
|
||||
return {};
|
||||
}
|
||||
|
||||
static void ReleaseWakeLockLinux(const QDBusObjectPath& lock) {
|
||||
if (!QDBusConnection::sessionBus().isConnected()) {
|
||||
return;
|
||||
}
|
||||
QDBusInterface unlocker(QString::fromLatin1("org.freedesktop.portal.Desktop"), lock.path(),
|
||||
QString::fromLatin1("org.freedesktop.portal.Request"));
|
||||
unlocker.call(QString::fromLatin1("Close"));
|
||||
}
|
||||
#endif // __unix__
|
||||
|
||||
void GMainWindow::PreventOSSleep() {
|
||||
#ifdef _WIN32
|
||||
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
|
||||
#elif defined(HAVE_SDL2)
|
||||
SDL_DisableScreenSaver();
|
||||
#if defined(__unix__) && !defined(__APPLE__)
|
||||
auto reply = HoldWakeLockLinux(winId());
|
||||
if (reply) {
|
||||
wake_lock = std::move(reply.value());
|
||||
}
|
||||
#endif // defined(__unix__) && !defined(__APPLE__)
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user