#include "bar/config.h" #include "bar/integration/dbus.h" #include "bar/integration/mpris.h" #include "bar/modules.h" #include "bar/util.h" #include #include typedef struct { redraw_fn_t redraw; void *redraw_data; mpris_monitor_t *monitor; mpris_player_t state; } media_module_t; static void on_mpris_update(const mpris_player_t *player, void *data) { media_module_t *m = data; m->state.status = player->status; if (player->art) { pixman_image_ref(player->art); } if (m->state.art) { pixman_image_unref(m->state.art); } m->state.art = player->art; assign_str(&m->state.title, player->title); assign_str(&m->state.artist, player->artist); m->state.player_name[sizeof(m->state.player_name) - 1] = '\0'; strncpy(m->state.player_name, player->player_name, sizeof(m->state.player_name) - 1); m->state.art_path[sizeof(m->state.art_path) - 1] = '\0'; strncpy(m->state.art_path, player->art_path, sizeof(m->state.art_path) - 1); m->redraw(m->redraw_data); } static size_t media_render(module_t *mod, segment_t *out) { mpris_player_t p = ((media_module_t *)mod->internal)->state; if (p.status != MPRIS_STATE_STOPPED && p.title && p.title[0] != '\0') { *out = (segment_t){ .is_multi_line = true, .top = p.artist, .bottom = p.title, .top_fg = CLR_MUTED, .bottom_fg = CLR_FG, .bg = CLR_BG, .bg_image = p.art, }; } else { *out = (segment_t){ .text = " No media", .fg = CLR_FG, .bg = CLR_BG, }; } return 1; } static void media_destroy(module_t *mod) { media_module_t *m = mod->internal; if (m->state.art) pixman_image_unref(m->state.art); if (m->monitor) mpris_monitor_destroy(m->monitor); if (m->state.title) free(m->state.title); if (m->state.artist) free(m->state.artist); free(m); free(mod); } module_t *media_module_new(dbus_ctx_t *dbus, redraw_fn_t fn, void *data) { module_t *mod = malloc(sizeof *mod); media_module_t *state = calloc(1, sizeof *state); if (!mod || !state) { if (mod) free(mod); if (state) free(state); return nullptr; } state->redraw = fn; state->redraw_data = data; *mod = (module_t){ .render = media_render, .destroy = media_destroy, .internal = state}; if (dbus) state->monitor = mpris_monitor_new(dbus_ctx_get_conn(dbus), on_mpris_update, state); return mod; }