diff options
| author | Louis Burda <quent.burda@gmail.com> | 2022-01-07 17:45:20 +0100 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2022-01-07 18:17:19 +0100 |
| commit | 43282adc30aadefb563ef26bea1233d4cbdb6007 (patch) | |
| tree | 4f652c6f9052f310ec6ed9c9148265ef476ae9ba /src/mpris.c | |
| parent | 7902429e5d69bb6aa57c6f1411b163d3e037e0e1 (diff) | |
| download | tmus-43282adc30aadefb563ef26bea1233d4cbdb6007.tar.gz tmus-43282adc30aadefb563ef26bea1233d4cbdb6007.zip | |
Added MPRIS control
Diffstat (limited to 'src/mpris.c')
| -rw-r--r-- | src/mpris.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/src/mpris.c b/src/mpris.c new file mode 100644 index 0000000..34c0ab3 --- /dev/null +++ b/src/mpris.c @@ -0,0 +1,147 @@ +#include "log.h" +#include "mpris.h" +#include "player.h" +#include "util.h" + +#include <stdbool.h> + +int dbus_active; +DBusConnection *dbus_conn; + +static const char *const dbus_mpris_caps[] = { + "CanPlay", + "CanPause", + "CanGoPrevious", + "CanGoNext", + "CanControl" +}; + +void +dbus_init(void) +{ + DBusError err; + int ret; + + dbus_active = 0; + + dbus_error_init(&err); + + /* dont fail if dbus not available, not everyone has + * it or needs it to play music */ + dbus_conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err) || !dbus_conn) { + dbus_error_free(&err); + return; + } + + /* register as MPRIS compliant player for events */ + ret = dbus_bus_request_name(dbus_conn, "org.mpris.MediaPlayer2.tmus", + DBUS_NAME_FLAG_REPLACE_EXISTING, &err); + if (dbus_error_is_set(&err)) + PANIC("Failed to register as MPRIS service\n"); + + log_info("DBus active!\n"); + + dbus_active = 1; + + dbus_error_free(&err); +} + +void +dbus_handle_getall(DBusMessage *msg) +{ + DBusMessage *reply; + DBusError err; + DBusMessageIter iter, aiter, eiter, viter; + const char *interface; + dbus_bool_t can; + int i, ok; + + dbus_error_init(&err); + + ok = dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &interface); + if (ok && strcmp(interface, "org.mpris.MediaPlayer2.Player")) { + dbus_error_free(&err); + return; + } + + reply = dbus_message_new_method_return(msg); + + /* TODO: change to more sane api like gio and gdbus (?) */ + + /* connect argument iter to message */ + dbus_message_iter_init_append(reply, &iter); + + /* add array of dict entries { string : variant } */ + ASSERT(dbus_message_iter_open_container(&iter, 'a', "{sv}", &aiter)); + + for (i = 0; i < ARRLEN(dbus_mpris_caps); i++) { + /* add dict entry */ + ASSERT(dbus_message_iter_open_container(&aiter, + 'e', NULL, &eiter)); + + /* string key */ + ASSERT(dbus_message_iter_append_basic(&eiter, + 's', &dbus_mpris_caps[i])); + + /* variant container */ + ASSERT(dbus_message_iter_open_container(&eiter, + 'v', "b", &viter)); + + can = true; /* bool value */ + ASSERT(dbus_message_iter_append_basic(&viter, 'b', &can)); + + dbus_message_iter_close_container(&eiter, &viter); + dbus_message_iter_close_container(&aiter, &eiter); + } + + dbus_message_iter_close_container(&iter, &aiter); + + dbus_connection_send(dbus_conn, reply, NULL); + + dbus_message_unref(reply); + + dbus_error_free(&err); +} + +void +dbus_update(void) +{ + DBusMessage *msg; + const char *interface; + const char *method; + + if (!dbus_active) return; + + dbus_connection_read_write(dbus_conn, 0); + msg = dbus_connection_pop_message(dbus_conn); + if (msg == NULL) return; + + method = dbus_message_get_member(msg); + interface = dbus_message_get_interface(msg); + if (!strcmp(interface, "org.freedesktop.DBus.Properties")) { + log_info("DBus: Properties requested\n"); + if (!strcmp(method, "GetAll")) + dbus_handle_getall(msg); + } else if (!strcmp(interface, "org.mpris.MediaPlayer2.Player")) { + log_info("MPRIS: Method %s\n", method); + if (!strcmp(method, "PlayPause")) { + player_toggle_pause(); + } else if (!strcmp(method, "Next")) { + player_next(); + } else if (!strcmp(method, "Previous")) { + player_prev(); + } + } + + dbus_message_unref(msg); +} + +void +dbus_end(void) +{ + if (!dbus_active) return; + + dbus_connection_unref(dbus_conn); +} + |
