[dbus] Also check if gamemode is enabled with D-Bus

pull/595/head
jackun 3 years ago
parent 7e3a56d356
commit 31e879215a
No known key found for this signature in database
GPG Key ID: 119DB3F1D05A9ED3

@ -150,18 +150,7 @@ bool dbus_manager::get_media_player_metadata(metadata& meta, std::string name) {
return true;
}
bool dbus_manager::init(const std::string& requested_player) {
if (!requested_player.empty()) {
m_requested_player = "org.mpris.MediaPlayer2." + requested_player;
} else
m_requested_player.clear();
if (m_inited) {
select_active_player();
return true;
}
bool dbus_manager::init_internal() {
if (!m_dbus_ldr.IsLoaded() && !m_dbus_ldr.Load("libdbus-1.so.3")) {
SPDLOG_ERROR("Could not load libdbus-1.so.3");
return false;
@ -182,13 +171,34 @@ bool dbus_manager::init(const std::string& requested_player) {
m_dbus_ldr.bus_get_unique_name(m_dbus_conn));
dbus_list_name_to_owner();
connect_to_signals();
select_active_player();
m_inited = true;
return true;
}
bool dbus_manager::init(Service srv) {
if (!m_inited && !init_internal())
return false;
connect_to_signals(srv);
m_active_srvs |= srv;
return true;
}
bool dbus_manager::init_mpris(const std::string& requested_player) {
if (!requested_player.empty()) {
m_requested_player = "org.mpris.MediaPlayer2." + requested_player;
} else
m_requested_player.clear();
if (m_active_srvs & SRV_MPRIS) {
select_active_player();
return true;
}
SPDLOG_WARN("D-Bus hasn't been inited yet.");
return false;
}
bool dbus_manager::select_active_player() {
auto old_active_player = m_active_player;
m_active_player = "";
@ -234,20 +244,23 @@ bool dbus_manager::select_active_player() {
}
}
void dbus_manager::deinit() {
void dbus_manager::deinit(Service srv) {
if (!m_inited) return;
m_active_srvs &= ~srv;
if (m_dbus_conn)
disconnect_from_signals(srv);
// unreference system bus connection instead of closing it
if (m_dbus_conn) {
disconnect_from_signals();
if (m_dbus_conn && !m_active_srvs) {
m_dbus_ldr.connection_unref(m_dbus_conn);
m_dbus_conn = nullptr;
m_dbus_ldr.error_free(&m_error);
m_inited = false;
}
m_dbus_ldr.error_free(&m_error);
m_inited = false;
}
dbus_manager::~dbus_manager() { deinit(); }
dbus_manager::~dbus_manager() { deinit(SRV_ALL); }
DBusHandlerResult dbus_manager::filter_signals(DBusConnection* conn,
DBusMessage* msg,
@ -320,8 +333,46 @@ bool dbus_manager::handle_name_owner_changed(DBusMessage* _msg,
return true;
}
void dbus_manager::connect_to_signals() {
bool dbus_manager::gamemode_enabled(int32_t pid) {
if (!m_inited)
return false;
auto reply =
DBusMessage_wrap::new_method_call(
"com.feralinteractive.GameMode", "/com/feralinteractive/GameMode",
"com.feralinteractive.GameMode", "QueryStatus", &dbus_mgr.dbus())
.argument(pid)
.send_with_reply_and_block(dbus_mgr.get_conn(), DBUS_TIMEOUT);
if (!reply) return false;
auto iter = reply.iter();
if (!iter.is_signed()) return false;
return !!iter.get_primitive<int32_t>();
}
bool dbus_manager::handle_game_registered(DBusMessage* _msg,
const char* sender) {
auto iter = DBusMessageIter_wrap(_msg, &m_dbus_ldr);
auto pid = iter.get_primitive<int32_t>();
iter.next();
auto path = iter.get_primitive<std::string>();
SPDLOG_INFO("Game registered: {} '{}'", pid, path);
return true;
}
bool dbus_manager::handle_game_unregistered(DBusMessage* _msg,
const char* sender) {
auto iter = DBusMessageIter_wrap(_msg, &m_dbus_ldr);
auto pid = iter.get_primitive<int32_t>();
iter.next();
auto path = iter.get_primitive<std::string>();
SPDLOG_INFO("Game unregistered: {} '{}'", pid, path);
return true;
}
void dbus_manager::connect_to_signals(Service srv) {
for (auto kv : m_signals) {
if (!(kv.srv & srv)) continue;
auto signal = format_signal(kv);
m_dbus_ldr.bus_add_match(m_dbus_conn, signal.c_str(), &m_error);
if (m_dbus_ldr.error_is_set(&m_error)) {
@ -336,10 +387,11 @@ void dbus_manager::connect_to_signals() {
start_thread();
}
void dbus_manager::disconnect_from_signals() {
void dbus_manager::disconnect_from_signals(Service srv) {
m_dbus_ldr.connection_remove_filter(m_dbus_conn, filter_signals,
reinterpret_cast<void*>(this));
for (auto kv : m_signals) {
if (!(kv.srv & srv)) continue;
auto signal = format_signal(kv);
m_dbus_ldr.bus_remove_match(m_dbus_conn, signal.c_str(), &m_error);
if (m_dbus_ldr.error_is_set(&m_error)) {

@ -137,7 +137,10 @@ bool DBusMessageIter_wrap::is_array() const noexcept {
template <class T>
auto DBusMessageIter_wrap::get_primitive() -> T {
auto requested_type = detail::dbus_type_identifier<T>;
if (requested_type != type()) {
if (type() == DBUS_TYPE_OBJECT_PATH && requested_type == DBUS_TYPE_STRING) {
// no special type, just a string
}
else if (requested_type != type()) {
SPDLOG_ERROR("Type mismatch: '{}' vs '{}'",
((char)requested_type), (char)type());
#ifndef NDEBUG

@ -55,7 +55,16 @@ namespace dbusmgr {
class dbus_manager;
using signal_handler_func = bool (dbus_manager::*)(DBusMessage*, const char*);
enum Service
{
SRV_NONE = 0,
SRV_MPRIS = (1ul << 0),
SRV_GAMEMODE = (1ul << 1),
SRV_ALL = 0xFFFFFFFF,
};
struct DBusSignal {
Service srv;
const char* intf;
const char* signal;
signal_handler_func handler;
@ -67,16 +76,20 @@ class dbus_manager {
~dbus_manager();
bool init(const std::string& requested_player);
void deinit();
bool init(Service srv);
bool init_mpris(const std::string& requested_player);
void deinit(Service srv);
bool get_media_player_metadata(metadata& meta, std::string name = "");
void connect_to_signals();
void disconnect_from_signals();
void connect_to_signals(Service srv);
void disconnect_from_signals(Service srv);
DBusConnection* get_conn() const { return m_dbus_conn; }
bool gamemode_enabled(int32_t pid);
libdbus_loader& dbus() { return m_dbus_ldr; }
protected:
bool init_internal();
void stop_thread();
void start_thread();
void dbus_thread();
@ -89,6 +102,8 @@ class dbus_manager {
bool handle_properties_changed(DBusMessage*, const char*);
bool handle_name_owner_changed(DBusMessage*, const char*);
bool handle_game_registered(DBusMessage*, const char*);
bool handle_game_unregistered(DBusMessage*, const char*);
void onNewPlayer(
metadata& meta); // A different player has become the active player
@ -105,12 +120,17 @@ class dbus_manager {
std::unordered_map<std::string, std::string> m_name_owners;
std::string m_requested_player;
std::string m_active_player;
uint32_t m_active_srvs = SRV_NONE;
const std::array<DBusSignal, 2> m_signals{{
{"org.freedesktop.DBus", "NameOwnerChanged",
{SRV_MPRIS, "org.freedesktop.DBus", "NameOwnerChanged",
&dbus_manager::handle_name_owner_changed},
{"org.freedesktop.DBus.Properties", "PropertiesChanged",
{SRV_MPRIS, "org.freedesktop.DBus.Properties", "PropertiesChanged",
&dbus_manager::handle_properties_changed},
// {SRV_GAMEMODE, "com.feralinteractive.GameMode", "GameRegistered",
// &dbus_manager::handle_game_registered},
// {SRV_GAMEMODE, "com.feralinteractive.GameMode", "GameUnregistered",
// &dbus_manager::handle_game_unregistered},
}};
};

@ -7,6 +7,7 @@
#include <errno.h>
#ifdef __gnu_linux__
#include <wordexp.h>
#include <unistd.h>
#endif
#include "imgui.h"
#include <iostream>
@ -780,11 +781,21 @@ parse_overlay_config(struct overlay_params *params,
#ifdef HAVE_DBUS
if (params->enabled[OVERLAY_PARAM_ENABLED_media_player]) {
dbusmgr::dbus_mgr.init(params->media_player_name);
if (dbusmgr::dbus_mgr.init(dbusmgr::SRV_MPRIS))
dbusmgr::dbus_mgr.init_mpris(params->media_player_name);
} else {
dbusmgr::dbus_mgr.deinit();
dbusmgr::dbus_mgr.deinit(dbusmgr::SRV_MPRIS);
main_metadata.meta.valid = false;
}
if (params->enabled[OVERLAY_PARAM_ENABLED_gamemode])
{
if (dbusmgr::dbus_mgr.init(dbusmgr::SRV_GAMEMODE))
HUDElements.gamemode_bol = dbusmgr::dbus_mgr.gamemode_enabled(getpid());
}
else
dbusmgr::dbus_mgr.deinit(dbusmgr::SRV_GAMEMODE);
#endif
if(!params->output_file.empty()) {

Loading…
Cancel
Save