You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MangoHud/src/dbus_info.h

149 lines
3.8 KiB
C++

#pragma once
#ifndef MANGOHUD_DBUS_INFO_H
#define MANGOHUD_DBUS_INFO_H
#ifdef HAVE_DBUS
#include <array>
#include <functional>
#include <map>
#include <mutex>
#include <stdexcept>
#include <string>
#include <thread>
#include <unordered_map>
#include <vector>
#include "loaders/loader_dbus.h"
struct metadata {
// std::vector<std::string> artists;
std::string artists; // pre-concatenate
std::string title;
std::string album;
std::string something;
std::string artUrl;
bool playing = false;
bool valid = false;
bool got_song_data = false;
bool got_playback_data = false;
};
struct mp_fmt
{
std::string text;
float width;
};
struct mutexed_metadata {
std::mutex mtx;
metadata meta;
struct {
float pos;
float longest;
int dir = -1;
bool needs_recalc = true;
std::vector<mp_fmt> formatted;
} ticker;
};
enum SignalType {
ST_NAMEOWNERCHANGED,
ST_PROPERTIESCHANGED,
};
extern struct mutexed_metadata main_metadata;
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;
};
class dbus_manager {
public:
dbus_manager() {}
~dbus_manager();
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(Service srv);
void disconnect_from_signals(Service srv);
DBusConnection* get_conn() const { return m_dbus_conn; }
bool gamemode_enabled(pid_t pid);
libdbus_loader& dbus() { return m_dbus_ldr; }
protected:
bool init_internal();
void stop_thread();
void start_thread();
void dbus_thread();
bool dbus_list_name_to_owner();
bool select_active_player();
static DBusHandlerResult filter_signals(DBusConnection*, DBusMessage*,
void*);
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
void onNoPlayer(); // There is no longer any player active
void onPlayerUpdate(
metadata& meta); // The active player has sent an update
DBusError m_error;
DBusConnection* m_dbus_conn = nullptr;
bool m_quit = false;
bool m_inited = false;
std::thread m_thread;
libdbus_loader m_dbus_ldr;
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{{
{SRV_MPRIS, "org.freedesktop.DBus", "NameOwnerChanged",
&dbus_manager::handle_name_owner_changed},
{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},
}};
};
extern dbus_manager dbus_mgr;
} // namespace dbusmgr
bool get_media_player_metadata(dbusmgr::dbus_manager& dbus, const std::string& name, metadata& meta);
#endif // HAVE_DBUS
#endif //MANGOHUD_DBUS_INFO_H