unfinished linux backend

This commit is contained in:
EinTim23 2024-11-05 20:22:11 +01:00
parent 84e4250a7f
commit 9316276dbc
6 changed files with 318 additions and 3 deletions

3
.gitmodules vendored
View File

@ -13,3 +13,6 @@
[submodule "vendor/wxWidgets"]
path = vendor/wxWidgets
url = https://github.com/wxWidgets/wxWidgets.git
[submodule "vendor/libdbus"]
path = vendor/libdbus
url = https://gitlab.freedesktop.org/dbus/dbus.git

View File

@ -18,6 +18,7 @@ add_executable (PlayerLink ${SOURCES})
set_property(TARGET PlayerLink PROPERTY CXX_STANDARD 20)
add_subdirectory("vendor")
set(LIBRARIES discord-rpc libcurl_static mbedcrypto mbedx509 mbedtls wxmono)
set(INCLUDES vendor vendor/libdbus vendor/wxWidgets/include)
#use windows subsystem to disable console window and link winrt
if(WIN32)
@ -32,6 +33,9 @@ elseif(APPLE)
else()
message(FATAL_ERROR "MediaRemote framework not found.")
endif()
elseif(UNIX AND NOT APPLE)
list(APPEND LIBRARIES dbus)
list(APPEND INCLUDES "${CMAKE_BINARY_DIR}/vendor/dbus")
endif()
#search directories for the autogenerated wxwidgets setup.h file for all plattforms
@ -42,7 +46,7 @@ file(GLOB wx_setup_dir
)
if(wx_setup_dir)
message(STATUS "wxWidgets setup.h directory found: ${wx_setup_dir}")
target_include_directories(PlayerLink PRIVATE vendor vendor/wxWidgets/include ${wx_setup_dir})
target_include_directories(PlayerLink PRIVATE ${INCLUDES} ${wx_setup_dir})
else()
message(FATAL_ERROR "wx/setup.h not found. Please check your wxWidgets build configuration.")
endif()

View File

@ -1,5 +1,182 @@
#if !defined(_WIN32) && !defined(__APPLE__)
#include <dbus/dbus.h>
#include <iostream>
#include "../backend.hpp"
std::shared_ptr<MediaInfo> backend::getMediaInformation() { return nullptr; }
bool initialized = false;
DBusConnection* conn = nullptr;
std::string getActivePlayer(DBusConnection* conn) {
DBusMessage* msg;
DBusMessageIter args;
DBusError err;
dbus_error_init(&err);
msg = dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
"ListNames");
DBusMessage* reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
dbus_message_unref(msg);
if (!reply) {
dbus_error_free(&err);
return "";
}
dbus_message_iter_init(reply, &args);
DBusMessageIter sub;
dbus_message_iter_recurse(&args, &sub);
std::string active_player;
while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) {
const char* name;
dbus_message_iter_get_basic(&sub, &name);
if (std::string(name).find("org.mpris.MediaPlayer2.") == 0) {
active_player = name;
break;
}
dbus_message_iter_next(&sub);
}
dbus_message_unref(reply);
return active_player;
}
void getNowPlaying(DBusConnection* conn, const std::string& player) {
DBusMessage* msg;
DBusMessageIter args;
DBusError err;
dbus_error_init(&err);
msg = dbus_message_new_method_call(player.c_str(), "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties",
"Get");
const char* iface = "org.mpris.MediaPlayer2.Player";
const char* prop = "Metadata";
dbus_message_append_args(msg, DBUS_TYPE_STRING, &iface, DBUS_TYPE_STRING, &prop, DBUS_TYPE_INVALID);
DBusMessage* reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
dbus_message_unref(msg);
if (!reply) {
std::cerr << "Failed to get metadata: " << (err.message ? err.message : "Unknown error") << std::endl;
dbus_error_free(&err);
return;
}
dbus_message_iter_init(reply, &args);
if (dbus_message_iter_get_arg_type(&args) == DBUS_TYPE_VARIANT) {
DBusMessageIter variant;
dbus_message_iter_recurse(&args, &variant);
if (dbus_message_iter_get_arg_type(&variant) == DBUS_TYPE_ARRAY) {
DBusMessageIter array_iter;
dbus_message_iter_recurse(&variant, &array_iter);
while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_DICT_ENTRY) {
DBusMessageIter dict_entry;
dbus_message_iter_recurse(&array_iter, &dict_entry);
const char* key;
dbus_message_iter_get_basic(&dict_entry, &key);
dbus_message_iter_next(&dict_entry);
if (std::string(key) == "xesam:title") {
DBusMessageIter value_variant;
dbus_message_iter_recurse(&dict_entry, &value_variant);
if (dbus_message_iter_get_arg_type(&value_variant) == DBUS_TYPE_STRING) {
const char* title;
dbus_message_iter_get_basic(&value_variant, &title);
std::cout << "Title: " << title << std::endl;
}
} else if (std::string(key) == "xesam:artist") {
DBusMessageIter value_variant;
dbus_message_iter_recurse(&dict_entry, &value_variant);
if (dbus_message_iter_get_arg_type(&value_variant) == DBUS_TYPE_ARRAY) {
DBusMessageIter artist_array;
dbus_message_iter_recurse(&value_variant, &artist_array);
std::cout << "Artist(s): ";
bool first = true;
while (dbus_message_iter_get_arg_type(&artist_array) == DBUS_TYPE_STRING) {
const char* artist;
dbus_message_iter_get_basic(&artist_array, &artist);
if (!first)
std::cout << ", ";
std::cout << artist;
first = false;
dbus_message_iter_next(&artist_array);
}
std::cout << std::endl;
}
} else if (std::string(key) == "mpris:length") {
DBusMessageIter value_variant;
dbus_message_iter_recurse(&dict_entry, &value_variant);
int arg_type = dbus_message_iter_get_arg_type(&value_variant);
if (arg_type == DBUS_TYPE_INT64 || arg_type == DBUS_TYPE_UINT64) {
int64_t length;
dbus_message_iter_get_basic(&value_variant, &length);
std::cout << "Length (Duration): " << length / 1000000.0 << " seconds" << std::endl;
}
}
dbus_message_iter_next(&array_iter);
}
}
} else {
std::cerr << "Unexpected reply type for Metadata" << std::endl;
}
dbus_message_unref(reply);
msg = dbus_message_new_method_call(player.c_str(), "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties",
"Get");
prop = "Position";
dbus_message_append_args(msg, DBUS_TYPE_STRING, &iface, DBUS_TYPE_STRING, &prop, DBUS_TYPE_INVALID);
reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
dbus_message_unref(msg);
if (!reply) {
std::cerr << "Failed to get position: " << (err.message ? err.message : "Unknown error") << std::endl;
dbus_error_free(&err);
return;
}
dbus_message_iter_init(reply, &args);
if (dbus_message_iter_get_arg_type(&args) == DBUS_TYPE_VARIANT) {
DBusMessageIter variant;
dbus_message_iter_recurse(&args, &variant);
int arg_type = dbus_message_iter_get_arg_type(&variant);
if (arg_type == DBUS_TYPE_INT64 || arg_type == DBUS_TYPE_UINT64) {
int64_t position;
dbus_message_iter_get_basic(&variant, &position);
std::cout << "Current Position: " << position / 1000000.0 << " seconds" << std::endl;
}
}
dbus_message_unref(reply);
}
std::shared_ptr<MediaInfo> backend::getMediaInformation() {
if (!initialized) {
DBusError err;
dbus_error_init(&err);
conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
if (!conn) {
dbus_error_free(&err);
return nullptr;
}
initialized = true;
}
std::string player = getActivePlayer(conn);
if (player == "")
return nullptr;
getNowPlaying(conn, player);
return nullptr;
}
bool backend::toggleAutostart(bool enabled) { return false; }
#endif

View File

@ -19,3 +19,6 @@ set(wxBUILD_MONOLITHIC ON)
set(wxUSE_GUI ON)
set(wxUSE_WEBVIEW OFF)
add_subdirectory("wxWidgets")
if(UNIX AND NOT APPLE)
add_subdirectory("dbus")
endif()

127
vendor/dbus/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,127 @@
project(dbus-lib)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/vendor/libdbus/cmake")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/vendor/libdbus/cmake/modules")
SET(DBUS_DIR ${CMAKE_SOURCE_DIR}/vendor/libdbus/dbus)
include(MacrosAutotools)
autoinit(${CMAKE_SOURCE_DIR}/vendor/libdbus/configure.ac)
autoversion(dbus)
include (TestBigEndian)
test_big_endian(WORDS_BIGENDIAN)
set(DBUS_PATCH_VERSION "0")
include(Macros)
string(TIMESTAMP DBUS_BUILD_TIMESTAMP "%Y%m%d%H%M" UTC)
set(BUILD_FILEVERSION ${DBUS_MAJOR_VERSION},${DBUS_MINOR_VERSION},${DBUS_MICRO_VERSION},${DBUS_PATCH_VERSION})
set(BUILD_TIMESTAMP ${DBUS_BUILD_TIMESTAMP})
if(UNIX AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(DBUS_LINUX 1)
endif()
set(_GNU_SOURCE 1)
set(DBUS_LIBRARIES dbus-1)
set(DBUS_INTERNAL_LIBRARIES dbus-internal)
set(DBUS_INTERNAL_ADD_LIBRARY_OPTIONS STATIC)
set(DBUS_INTERNAL_CLIENT_DEFINITIONS "-DDBUS_COMPILATION")
add_definitions(-DHAVE_CONFIG_H)
include(ConfigureChecks)
set(DBUS_SESSION_SOCKET_DIR "" CACHE STRING "Default directory for session socket")
set(DBUS_SYSTEM_PID_FILE ${DBUS_RUNSTATEDIR}/dbus/pid)
set(DBUS_CONSOLE_AUTH_DIR "" CACHE STRING "Directory to check for pam_console/pam_foreground flag files, or empty to ignore")
set(DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=${DBUS_RUNSTATEDIR}/dbus/system_bus_socket" CACHE STRING "system bus default address")
set(DBUS_SESSION_SOCKET_DIR "" CACHE STRING "Default directory for session socket")
if(UNIX)
if (CMAKE_CROSSCOMPILING)
if (NOT DBUS_SESSION_SOCKET_DIR)
message(FATAL_ERROR "cannot autodetect session socket directory "
"when crosscompiling, pass -DDBUS_SESSION_SOCKET_DIR=...")
endif()
elseif(NOT $ENV{TMPDIR} STREQUAL "")
set(DBUS_SESSION_SOCKET_DIR $ENV{TMPDIR})
elseif(NOT $ENV{TEMP} STREQUAL "")
set(DBUS_SESSION_SOCKET_DIR $ENV{TEMP})
elseif(NOT $ENV{TMP} STREQUAL "")
set(DBUS_SESSION_SOCKET_DIR $ENV{TMP})
else()
set(DBUS_SESSION_SOCKET_DIR /tmp)
endif()
endif()
set(DBUS_SESSION_BUS_LISTEN_ADDRESS "unix:tmpdir=${DBUS_SESSION_SOCKET_DIR}" CACHE STRING "session bus default listening address")
set(DBUS_SESSION_BUS_CONNECT_ADDRESS "autolaunch:" CACHE STRING "session bus fallback address for clients")
set(DBUS_SYSTEM_CONFIG_FILE ${DBUS_DATADIR}/dbus-1/system.conf)
set(DBUS_SESSION_CONFIG_FILE ${DBUS_DATADIR}/dbus-1/session.conf)
set(DBUS_MACHINE_UUID_FILE ${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/dbus/machine-id)
set(DBUS_USER "messagebus")
set(DBUS_TEST_USER "nobody")
set(DBUS_SESSION_CONF_MAYBE_AUTH_EXTERNAL "<auth>EXTERNAL</auth>")
set(DBUS_DAEMON_NAME "dbus-daemon" CACHE STRING "The name of the dbus daemon executable")
configure_file(${CMAKE_SOURCE_DIR}/vendor/libdbus/cmake/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h )
configure_file(${DBUS_DIR}/dbus-arch-deps.h.in ${CMAKE_CURRENT_BINARY_DIR}/dbus/dbus-arch-deps.h )
add_definitions(-DDBUS_COMPILATION)
set (DBUS_LIB_SOURCES
${DBUS_DIR}/dbus-address.c
${DBUS_DIR}/dbus-auth.c
${DBUS_DIR}/dbus-bus.c
${DBUS_DIR}/dbus-test-tap.c
${DBUS_DIR}/dbus-connection.c
${DBUS_DIR}/dbus-credentials.c
${DBUS_DIR}/dbus-errors.c
${DBUS_DIR}/dbus-keyring.c
${DBUS_DIR}/dbus-marshal-header.c
${DBUS_DIR}/dbus-marshal-byteswap.c
${DBUS_DIR}/dbus-marshal-recursive.c
${DBUS_DIR}/dbus-marshal-validate.c
${DBUS_DIR}/dbus-message.c
${DBUS_DIR}/dbus-misc.c
${DBUS_DIR}/dbus-nonce.c
${DBUS_DIR}/dbus-object-tree.c
${DBUS_DIR}/dbus-pending-call.c
${DBUS_DIR}/dbus-resources.c
${DBUS_DIR}/dbus-server.c
${DBUS_DIR}/dbus-server-socket.c
${DBUS_DIR}/dbus-server-debug-pipe.c
${DBUS_DIR}/dbus-sha.c
${DBUS_DIR}/dbus-signature.c
${DBUS_DIR}/dbus-syntax.c
${DBUS_DIR}/dbus-timeout.c
${DBUS_DIR}/dbus-threads.c
${DBUS_DIR}/dbus-transport.c
${DBUS_DIR}/dbus-transport-socket.c
${DBUS_DIR}/dbus-watch.c
${DBUS_DIR}/dbus-transport-unix.c
${DBUS_DIR}/dbus-server-unix.c
${DBUS_DIR}/dbus-dataslot.c
${DBUS_DIR}/dbus-file.c
${DBUS_DIR}/dbus-hash.c
${DBUS_DIR}/dbus-internals.c
${DBUS_DIR}/dbus-list.c
${DBUS_DIR}/dbus-marshal-basic.c
${DBUS_DIR}/dbus-memory.c
${DBUS_DIR}/dbus-mempool.c
${DBUS_DIR}/dbus-string.c
${DBUS_DIR}/dbus-sysdeps.c
${DBUS_DIR}/dbus-pipe.c
${DBUS_DIR}/dbus-file-unix.c
${DBUS_DIR}/dbus-pipe-unix.c
${DBUS_DIR}/dbus-sysdeps-unix.c
${DBUS_DIR}/dbus-sysdeps-pthread.c
${DBUS_DIR}/dbus-userdb.c
)
file(GLOB libdbus_config_dir
"${CMAKE_BINARY_DIR}/vendor/dbus"
)
add_library(dbus STATIC ${DBUS_LIB_SOURCES})
target_include_directories(dbus PRIVATE ${libdbus_config_dir} ${CMAKE_SOURCE_DIR}/vendor/libdbus)

1
vendor/libdbus vendored Submodule

@ -0,0 +1 @@
Subproject commit fbd7a993fb966330e41c59634dafb212399d7a21