2020-05-29 12:21:05 +00:00
|
|
|
#include "dbus_client.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
void dbusQuery( DBusMessageIter *args, DBusMessage **msg, DBusConnection *conn,
|
|
|
|
const char *target, const char *object, const char *interface,
|
|
|
|
const char *method, const char **params ) {
|
|
|
|
DBusPendingCall *pending;
|
|
|
|
|
|
|
|
// create a new method call and check for errors
|
|
|
|
*msg = dbus_message_new_method_call( target, object, interface, method );
|
|
|
|
|
|
|
|
if ( *msg == NULL ) {
|
|
|
|
fprintf( stderr, "Message is NULL\n" );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
// append arguments
|
|
|
|
if ( params != NULL ) {
|
|
|
|
dbus_message_iter_init_append( *msg, args );
|
|
|
|
// iterate through params
|
|
|
|
for ( const char **param = params; *param; ++param ) {
|
|
|
|
if ( !dbus_message_iter_append_basic( args, DBUS_TYPE_STRING,
|
|
|
|
param ) ) {
|
|
|
|
fprintf( stderr, "Out Of Memory!\n" );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// send message and get a handle for a reply
|
|
|
|
if ( !dbus_connection_send_with_reply( conn, *msg, &pending, -1 ) ) {
|
|
|
|
fprintf( stderr, "Out Of Memory!\n" );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
if ( pending == NULL ) {
|
|
|
|
fprintf( stderr, "Pending Call is NULL\n" );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
dbus_connection_flush( conn );
|
|
|
|
dbus_message_unref( *msg );
|
|
|
|
|
|
|
|
// block until we recieve a reply
|
|
|
|
dbus_pending_call_block( pending );
|
|
|
|
|
|
|
|
// get the reply message
|
|
|
|
*msg = dbus_pending_call_steal_reply( pending );
|
|
|
|
if ( *msg == NULL ) {
|
|
|
|
fprintf( stderr, "Reply Null\n" );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
dbus_pending_call_unref( pending );
|
|
|
|
dbus_message_iter_init( *msg, args );
|
|
|
|
}
|
|
|
|
|
|
|
|
DBusConnection *dbusConnect() {
|
|
|
|
DBusError err;
|
|
|
|
|
|
|
|
dbus_error_init( &err );
|
|
|
|
DBusConnection *conn = dbus_bus_get( DBUS_BUS_SESSION, &err );
|
|
|
|
if ( dbus_error_is_set( &err ) ) {
|
|
|
|
fprintf( stderr, "Connection Error (%s)\n", err.message );
|
|
|
|
dbus_error_free( &err );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
if ( NULL == conn ) {
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
return conn;
|
|
|
|
}
|
|
|
|
|
|
|
|
void dbusDisconnect( DBusConnection *conn ) {
|
|
|
|
dbus_connection_close( conn );
|
|
|
|
}
|
|
|
|
|
|
|
|
char **dbusGetMediaPlayers( DBusConnection *conn ) {
|
|
|
|
DBusMessageIter args;
|
|
|
|
DBusMessageIter string;
|
|
|
|
DBusMessage *msg = NULL;
|
|
|
|
dbusQuery( &args, &msg, conn, "org.freedesktop.DBus",
|
|
|
|
"/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames",
|
|
|
|
NULL );
|
|
|
|
|
|
|
|
char **ret = malloc( sizeof( char * ) );
|
|
|
|
if ( ret == NULL ) {
|
|
|
|
fprintf( stderr, "Out of memory" );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
ret[0] = NULL;
|
|
|
|
size_t count = 0;
|
|
|
|
char *path = NULL;
|
|
|
|
do {
|
|
|
|
dbus_message_iter_recurse( &args, &string );
|
|
|
|
do {
|
|
|
|
dbus_message_iter_get_basic( &string, &path );
|
|
|
|
if ( strstr( path, "mpris" ) != NULL ) {
|
|
|
|
count++;
|
|
|
|
char **new = realloc( ret, ( count + 1 ) * sizeof( char * ) );
|
|
|
|
if ( new == NULL ) {
|
|
|
|
fprintf( stderr, "Out of memory" );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
ret = new;
|
|
|
|
ret[count - 1] = strdup( path );
|
|
|
|
if ( ret[count - 1] == NULL ) {
|
|
|
|
fprintf( stderr, "Out of memory" );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
ret[count] = NULL;
|
|
|
|
}
|
|
|
|
} while ( dbus_message_iter_next( &string ) );
|
|
|
|
} while ( dbus_message_iter_next( &args ) );
|
|
|
|
|
|
|
|
dbus_message_unref( msg );
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct song_metadata dbusGetSong( DBusConnection *conn, const char *player ) {
|
|
|
|
struct song_metadata ret = { 0 };
|
|
|
|
DBusMessageIter args;
|
|
|
|
DBusMessageIter array;
|
|
|
|
DBusMessageIter dict;
|
|
|
|
DBusMessageIter dict_entry;
|
|
|
|
DBusMessageIter variant;
|
|
|
|
DBusMessageIter artists;
|
|
|
|
DBusMessage *msg = NULL;
|
|
|
|
const char *params[3] = { "org.mpris.MediaPlayer2.Player", "Metadata",
|
|
|
|
NULL };
|
|
|
|
dbusQuery( &args, &msg, conn, player, "/org/mpris/MediaPlayer2",
|
|
|
|
"org.freedesktop.DBus.Properties", "Get", params );
|
|
|
|
|
|
|
|
char *meta_name = NULL;
|
|
|
|
char *meta_val = NULL;
|
|
|
|
dbus_message_iter_recurse( &args, &array );
|
|
|
|
dbus_message_iter_recurse( &array, &dict );
|
|
|
|
do {
|
|
|
|
dbus_message_iter_recurse( &dict, &dict_entry );
|
|
|
|
dbus_message_iter_get_basic( &dict_entry, &meta_name );
|
|
|
|
|
|
|
|
dbus_message_iter_next( &dict_entry );
|
|
|
|
dbus_message_iter_recurse( &dict_entry, &variant );
|
|
|
|
if ( !strcmp( meta_name, "xesam:artist" ) ) {
|
|
|
|
dbus_message_iter_recurse( &variant, &artists );
|
|
|
|
dbus_message_iter_get_basic( &artists, &meta_val );
|
|
|
|
ret.artist = strdup( meta_val );
|
2020-05-29 18:36:54 +00:00
|
|
|
} else if ( dbus_message_iter_get_arg_type( &variant ) == DBUS_TYPE_STRING ) {
|
2020-05-29 12:21:05 +00:00
|
|
|
dbus_message_iter_get_basic( &variant, &meta_val );
|
|
|
|
if ( !strcmp( meta_name, "xesam:title" ) )
|
|
|
|
ret.title = strdup( meta_val );
|
|
|
|
else if ( !strcmp( meta_name, "xesam:album" ) )
|
|
|
|
ret.album = strdup( meta_val );
|
|
|
|
else if ( !strcmp( meta_name, "xesam:url" ) )
|
|
|
|
ret.file = strdup( meta_val );
|
|
|
|
else if ( !strcmp( meta_name, "mpris:artUrl" ) )
|
|
|
|
ret.art_uri = strdup( meta_val );
|
|
|
|
}
|
|
|
|
} while ( dbus_message_iter_next( &dict ) );
|
|
|
|
|
|
|
|
dbus_message_unref( msg );
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void dbusPlayPause( DBusConnection *conn, const char *player ) {
|
|
|
|
DBusMessageIter args;
|
|
|
|
DBusMessage *msg = NULL;
|
|
|
|
dbusQuery( &args, &msg, conn, player, "/org/mpris/MediaPlayer2",
|
|
|
|
"org.mpris.MediaPlayer2.Player", "PlayPause", NULL );
|
|
|
|
dbus_message_unref( msg );
|
|
|
|
}
|
|
|
|
|
|
|
|
void dbusNext( DBusConnection *conn, const char *player ) {
|
|
|
|
DBusMessageIter args;
|
|
|
|
DBusMessage *msg = NULL;
|
|
|
|
dbusQuery( &args, &msg, conn, player, "/org/mpris/MediaPlayer2",
|
|
|
|
"org.mpris.MediaPlayer2.Player", "Next", NULL );
|
|
|
|
dbus_message_unref( msg );
|
|
|
|
}
|
|
|
|
|
|
|
|
void dbusPrev( DBusConnection *conn, const char *player ) {
|
|
|
|
DBusMessageIter args;
|
|
|
|
DBusMessage *msg = NULL;
|
|
|
|
dbusQuery( &args, &msg, conn, player, "/org/mpris/MediaPlayer2",
|
|
|
|
"org.mpris.MediaPlayer2.Player", "Previous", NULL );
|
|
|
|
dbus_message_unref( msg );
|
|
|
|
}
|
|
|
|
|
|
|
|
void dbusStop( DBusConnection *conn, const char *player ) {
|
|
|
|
DBusMessageIter args;
|
|
|
|
DBusMessage *msg = NULL;
|
|
|
|
dbusQuery( &args, &msg, conn, player, "/org/mpris/MediaPlayer2",
|
|
|
|
"org.mpris.MediaPlayer2.Player", "Stop", NULL );
|
|
|
|
dbus_message_unref( msg );
|
|
|
|
}
|
|
|
|
|
2020-05-29 18:45:39 +00:00
|
|
|
char *dbusStatus( DBusConnection *conn, const char *player ) {
|
2020-05-29 12:21:05 +00:00
|
|
|
DBusMessageIter args;
|
|
|
|
DBusMessageIter string;
|
|
|
|
DBusMessage *msg = NULL;
|
|
|
|
const char *params[3] = { "org.mpris.MediaPlayer2.Player", "PlaybackStatus",
|
|
|
|
NULL };
|
|
|
|
dbusQuery( &args, &msg, conn, player, "/org/mpris/MediaPlayer2",
|
|
|
|
"org.freedesktop.DBus.Properties", "Get", params );
|
|
|
|
|
|
|
|
char *meta = NULL;
|
|
|
|
dbus_message_iter_recurse( &args, &string );
|
|
|
|
dbus_message_iter_get_basic( &string, &meta );
|
2020-05-29 18:45:39 +00:00
|
|
|
char *ret = strdup( meta );
|
2020-05-29 12:21:05 +00:00
|
|
|
// free reply
|
|
|
|
dbus_message_unref( msg );
|
|
|
|
return ret;
|
|
|
|
}
|
2020-05-29 18:45:39 +00:00
|
|
|
|
|
|
|
bool dbusRunning( DBusConnection *conn, const char *player ) {
|
|
|
|
char *status = dbusStatus( conn, player );
|
|
|
|
bool ret = strcmp( status, "Playing" ) == 0;
|
|
|
|
ret |= strcmp( status, "Paused" ) == 0;
|
|
|
|
free( status );
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool dbusPlaying( DBusConnection *conn, const char *player ) {
|
|
|
|
char *status = dbusStatus( conn, player );
|
|
|
|
bool ret = strcmp( status, "Playing" ) == 0;
|
|
|
|
free( status );
|
|
|
|
return ret;
|
|
|
|
}
|
2020-05-29 18:53:27 +00:00
|
|
|
|
|
|
|
void dbusFreePlyaers( char **dbus_players ) {
|
|
|
|
for( char **player = dbus_players; *player; ++player ) {
|
|
|
|
free( *player );
|
|
|
|
}
|
|
|
|
free( dbus_players );
|
|
|
|
}
|