mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-05 02:38:09 -05:00
[mpd] rating sticker translator
This commit is contained in:
parent
7c12ea1209
commit
bbc5d3787e
@ -1072,6 +1072,9 @@ dacp_propset_userrating(const char *value, struct evkeyvalq *query)
|
|||||||
|
|
||||||
mfi->rating = rating;
|
mfi->rating = rating;
|
||||||
|
|
||||||
|
/* rating is shared as MPD sticker `rating` */
|
||||||
|
listener_notify(LISTENER_STICKER);
|
||||||
|
|
||||||
/* We're not touching any string field in mfi, so it's safe to
|
/* We're not touching any string field in mfi, so it's safe to
|
||||||
* skip unicode_fixup_mfi() before the update
|
* skip unicode_fixup_mfi() before the update
|
||||||
*/
|
*/
|
||||||
|
@ -26,6 +26,8 @@ enum listener_event_type
|
|||||||
LISTENER_SPOTIFY = (1 << 9),
|
LISTENER_SPOTIFY = (1 << 9),
|
||||||
/* Last.fm status changes (enable/disable scrobbling) */
|
/* Last.fm status changes (enable/disable scrobbling) */
|
||||||
LISTENER_LASTFM = (1 << 10),
|
LISTENER_LASTFM = (1 << 10),
|
||||||
|
/* The sticker database has been modified (MPD) */
|
||||||
|
LISTENER_STICKER = (1 << 11),
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*notify)(short event_mask);
|
typedef void (*notify)(short event_mask);
|
||||||
|
334
src/mpd.c
334
src/mpd.c
@ -67,6 +67,8 @@ static struct commands_base *cmdbase;
|
|||||||
|
|
||||||
static struct evhttp *evhttpd;
|
static struct evhttp *evhttpd;
|
||||||
|
|
||||||
|
#define ALL_IDLE_LISTENER_EVENTS (LISTENER_PLAYER | LISTENER_QUEUE | LISTENER_VOLUME | LISTENER_SPEAKER | LISTENER_OPTIONS | LISTENER_DATABASE | LISTENER_UPDATE | LISTENER_STORED_PLAYLIST | LISTENER_STICKER)
|
||||||
|
|
||||||
struct evconnlistener *mpd_listener6;
|
struct evconnlistener *mpd_listener6;
|
||||||
struct evconnlistener *mpd_listener;
|
struct evconnlistener *mpd_listener;
|
||||||
|
|
||||||
@ -665,12 +667,14 @@ mpd_command_idle(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, s
|
|||||||
ctx->idle_events |= LISTENER_OPTIONS;
|
ctx->idle_events |= LISTENER_OPTIONS;
|
||||||
else if (0 == strcmp(argv[i], "stored_playlist"))
|
else if (0 == strcmp(argv[i], "stored_playlist"))
|
||||||
ctx->idle_events |= LISTENER_STORED_PLAYLIST;
|
ctx->idle_events |= LISTENER_STORED_PLAYLIST;
|
||||||
|
else if (0 == strcmp(argv[i], "sticker"))
|
||||||
|
ctx->idle_events |= LISTENER_STICKER;
|
||||||
else
|
else
|
||||||
DPRINTF(E_DBG, L_MPD, "Idle command for '%s' not supported\n", argv[i]);
|
DPRINTF(E_DBG, L_MPD, "Idle command for '%s' not supported\n", argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ctx->idle_events = LISTENER_PLAYER | LISTENER_QUEUE | LISTENER_VOLUME | LISTENER_SPEAKER | LISTENER_OPTIONS | LISTENER_DATABASE | LISTENER_UPDATE | LISTENER_STORED_PLAYLIST;
|
ctx->idle_events = ALL_IDLE_LISTENER_EVENTS;
|
||||||
|
|
||||||
// If events the client listens to occurred since the last idle call (or since the client connected,
|
// If events the client listens to occurred since the last idle call (or since the client connected,
|
||||||
// if it is the first idle call), notify immediately.
|
// if it is the first idle call), notify immediately.
|
||||||
@ -3244,6 +3248,285 @@ mpd_command_update(struct evbuffer *evbuf, int argc, char **argv, char **errmsg,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mpd_sticker_command {
|
||||||
|
const char *cmd;
|
||||||
|
int (*handler)(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, const char *name, const char *virtual_path, bool name_is_rating, struct media_file_info *mfi, int *rating, bool *set_rating);
|
||||||
|
int need_args;
|
||||||
|
int want_dir;
|
||||||
|
int get_mfi;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MPD_RATING_FACTOR 10.0
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_sticker_get(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, const char *name, const char *virtual_path, bool name_is_rating, struct media_file_info *mfi, int *rating, bool *set_rating)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (name_is_rating)
|
||||||
|
{
|
||||||
|
if (!mfi || !mfi->rating)
|
||||||
|
{
|
||||||
|
*errmsg = safe_asprintf("no such sticker");
|
||||||
|
ret = ACK_ERROR_NO_EXIST;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*rating = mfi->rating / MPD_RATING_FACTOR;
|
||||||
|
evbuffer_add_printf(evbuf, "sticker: rating=%d\n", *rating);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* |:todo:| real sticker implementation */
|
||||||
|
*errmsg = safe_asprintf("no such sticker");
|
||||||
|
ret = ACK_ERROR_NO_EXIST;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_sticker_set(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, const char *name, const char *virtual_path, bool name_is_rating, struct media_file_info *mfi, int *rating, bool *set_rating)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (name_is_rating)
|
||||||
|
{
|
||||||
|
ret = safe_atou32(argv[5], (unsigned int *) rating);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
*errmsg = safe_asprintf("rating '%s' doesn't convert to integer", argv[5]);
|
||||||
|
ret = ACK_ERROR_ARG;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*rating *= MPD_RATING_FACTOR;
|
||||||
|
*set_rating = 1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* |:todo:| real sticker implementation */
|
||||||
|
*errmsg = safe_asprintf("no such sticker");
|
||||||
|
ret = ACK_ERROR_NO_EXIST;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_sticker_delete(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, const char *name, const char *virtual_path, bool name_is_rating, struct media_file_info *mfi, int *rating, bool *set_rating)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (name_is_rating)
|
||||||
|
{
|
||||||
|
*rating = 0;
|
||||||
|
*set_rating = 1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* |:todo:| real sticker implementation */
|
||||||
|
*errmsg = safe_asprintf("no such sticker");
|
||||||
|
ret = ACK_ERROR_NO_EXIST;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_sticker_list(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, const char *name, const char *virtual_path, bool name_is_rating, struct media_file_info *mfi, int *rating, bool *set_rating)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (mfi && mfi->rating)
|
||||||
|
{
|
||||||
|
*rating = mfi->rating / MPD_RATING_FACTOR;
|
||||||
|
evbuffer_add_printf(evbuf, "sticker: rating=%d\n", *rating);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* |:todo:| real sticker implementation */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_sticker_find(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, const char *name, const char *virtual_path, bool name_is_rating, struct media_file_info *mfi, int *rating, bool *set_rating)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (name_is_rating && argc == 5)
|
||||||
|
{
|
||||||
|
struct query_params qp;
|
||||||
|
struct db_media_file_info dbmfi;
|
||||||
|
char *c1;
|
||||||
|
|
||||||
|
memset(&qp, 0, sizeof(struct query_params));
|
||||||
|
|
||||||
|
qp.type = Q_ITEMS;
|
||||||
|
qp.sort = S_VPATH;
|
||||||
|
qp.idx_type = I_NONE;
|
||||||
|
|
||||||
|
c1 = db_mprintf("(f.virtual_path LIKE '%s%%' AND f.rating != 0)", virtual_path);
|
||||||
|
if (!c1)
|
||||||
|
{
|
||||||
|
*errmsg = safe_asprintf("Out of memory");
|
||||||
|
ret = ACK_ERROR_UNKNOWN;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
qp.filter = c1;
|
||||||
|
|
||||||
|
ret = db_query_start(&qp);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
db_query_end(&qp);
|
||||||
|
free(qp.filter);
|
||||||
|
|
||||||
|
*errmsg = safe_asprintf("Could not start query");
|
||||||
|
ret = ACK_ERROR_UNKNOWN;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id))
|
||||||
|
{
|
||||||
|
ret = safe_atou32(dbmfi.rating, (unsigned int *) rating);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Error rating=%s doesn't convert to integer, song id: %s\n",
|
||||||
|
dbmfi.rating, dbmfi.id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*rating /= MPD_RATING_FACTOR;
|
||||||
|
if (!*rating)
|
||||||
|
/* inconsistent database */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = evbuffer_add_printf(evbuf,
|
||||||
|
"file: file:%s\n"
|
||||||
|
"sticker: rating=%d\n",
|
||||||
|
dbmfi.path,
|
||||||
|
*rating);
|
||||||
|
if (ret < 0)
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Error adding song to the evbuffer, song id: %s\n", dbmfi.id);
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
db_query_end(&qp);
|
||||||
|
free(qp.filter);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* |:todo:| MPD_STICKER_FIND with expressions */
|
||||||
|
|
||||||
|
/* |:todo:| real sticker implementation */
|
||||||
|
*errmsg = safe_asprintf("bad request");
|
||||||
|
ret = ACK_ERROR_ARG;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mpd_sticker_command mpd_sticker_handlers[] = {
|
||||||
|
{ "get", mpd_sticker_get, 5, 0, 0 },
|
||||||
|
{ "set", mpd_sticker_set, 6, 0, 0 },
|
||||||
|
{ "delete", mpd_sticker_delete, 5, 0, 0 },
|
||||||
|
{ "list", mpd_sticker_list, 4, 0, 1 },
|
||||||
|
{ "find", mpd_sticker_find, 5, 1, 0 },
|
||||||
|
{ NULL, NULL, 0, 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
mpd_add_idle_events(short event_mask);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command handler function for 'sticker'
|
||||||
|
*
|
||||||
|
* sticker get "noth here" rating
|
||||||
|
* ACK [2@0] {sticker} unknown sticker domain
|
||||||
|
*
|
||||||
|
* sticker get song "Al Cohn & Shorty Rogers/East Coast - West Coast Scene/04 Shorty Rogers - Cool Sunshine.flac" rating
|
||||||
|
* ACK [50@0] {sticker} no such sticker
|
||||||
|
*
|
||||||
|
* sticker get song "Al Cohn & Shorty Rogers/East Coast - West Coast Scene/03 Al Cohn - Serenade For Kathy.flac" rating
|
||||||
|
* sticker: rating=8
|
||||||
|
* OK
|
||||||
|
*
|
||||||
|
* From cantata:
|
||||||
|
* sticker set song "file:/srv/music/VA/The Electro Swing Revolution Vol 3 1 - Hop, Hop, Hop/13 Mr. Hotcut - You Are.mp3" rating "6"
|
||||||
|
* OK
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mpd_command_sticker(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, struct mpd_client_ctx *ctx)
|
||||||
|
{
|
||||||
|
struct mpd_sticker_command *cmd_param;
|
||||||
|
const char *cmd;
|
||||||
|
char *virtual_path = NULL;
|
||||||
|
const char *name = NULL;
|
||||||
|
bool name_is_rating = false;
|
||||||
|
struct media_file_info *mfi = NULL;
|
||||||
|
int rating = -1;
|
||||||
|
bool set_rating = false;
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (argc < 4)
|
||||||
|
{
|
||||||
|
*errmsg = safe_asprintf("not enough arguments");
|
||||||
|
return ACK_ERROR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[2], "song") != 0)
|
||||||
|
{
|
||||||
|
*errmsg = safe_asprintf("unknown sticker domain");
|
||||||
|
return ACK_ERROR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = argv[1];
|
||||||
|
for (i=0; i<(sizeof(mpd_sticker_handlers) / sizeof(struct mpd_sticker_command)); ++i)
|
||||||
|
{
|
||||||
|
cmd_param = &mpd_sticker_handlers[i];
|
||||||
|
if (cmd_param->cmd && strcmp(cmd, cmd_param->cmd) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!cmd_param->cmd)
|
||||||
|
{
|
||||||
|
*errmsg = safe_asprintf("bad request");
|
||||||
|
return ACK_ERROR_ARG;
|
||||||
|
}
|
||||||
|
if (argc < cmd_param->need_args)
|
||||||
|
{
|
||||||
|
*errmsg = safe_asprintf("not enough arguments");
|
||||||
|
return ACK_ERROR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > 4)
|
||||||
|
{
|
||||||
|
name = argv[4];
|
||||||
|
name_is_rating = strcmp(name, "rating") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual_path = prepend_slash(argv[3]);
|
||||||
|
|
||||||
|
if (cmd_param->get_mfi || (!cmd_param->want_dir && name_is_rating))
|
||||||
|
{
|
||||||
|
mfi = db_file_fetch_byvirtualpath(virtual_path);
|
||||||
|
if (!mfi)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Virtual path not found: %s\n", virtual_path);
|
||||||
|
*errmsg = safe_asprintf("unknown sticker domain");
|
||||||
|
free(virtual_path);
|
||||||
|
return ACK_ERROR_ARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = cmd_param->handler(evbuf, argc, argv, errmsg, name, virtual_path, name_is_rating, mfi, &rating, &set_rating);
|
||||||
|
|
||||||
|
if (ret == 0 && mfi && set_rating && mfi->rating != rating)
|
||||||
|
{
|
||||||
|
DPRINTF(E_DBG, L_MPD, "STICKER notification for changed rating: %d -> %d\n", mfi->rating, rating);
|
||||||
|
mfi->rating = rating;
|
||||||
|
/* Note, that a DATABASE event is triggered, but the
|
||||||
|
* client actually expects a sticker event, so add it here. */
|
||||||
|
mpd_add_idle_events(LISTENER_STICKER);
|
||||||
|
db_file_update(mfi);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(virtual_path);
|
||||||
|
|
||||||
|
if (mfi)
|
||||||
|
free_mfi(mfi, 0);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static int
|
static int
|
||||||
mpd_command_rescan(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, struct mpd_client_ctx *ctx)
|
mpd_command_rescan(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, struct mpd_client_ctx *ctx)
|
||||||
@ -4298,7 +4581,7 @@ static struct mpd_command mpd_handlers[] =
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
.mpdcommand = "sticker",
|
.mpdcommand = "sticker",
|
||||||
.handler = mpd_command_ignore
|
.handler = mpd_command_sticker
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4742,6 +5025,7 @@ mpd_accept_conn_cb(struct evconnlistener *listener,
|
|||||||
sockaddr_to_string(address, addr_str, sizeof(addr_str));
|
sockaddr_to_string(address, addr_str, sizeof(addr_str));
|
||||||
client_ctx->authenticated = peer_address_is_trusted(addr_str);
|
client_ctx->authenticated = peer_address_is_trusted(addr_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
client_ctx->next = mpd_clients;
|
client_ctx->next = mpd_clients;
|
||||||
mpd_clients = client_ctx;
|
mpd_clients = client_ctx;
|
||||||
|
|
||||||
@ -4773,6 +5057,28 @@ mpd_accept_error_cb(struct evconnlistener *listener, void *ctx)
|
|||||||
DPRINTF(E_LOG, L_MPD, "Error occured %d (%s) on the listener.\n", err, evutil_socket_error_to_string(err));
|
DPRINTF(E_LOG, L_MPD, "Error occured %d (%s) on the listener.\n", err, evutil_socket_error_to_string(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mpd_add_idle_events(short event_mask)
|
||||||
|
{
|
||||||
|
struct mpd_client_ctx *client;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DPRINTF(E_DBG, L_MPD, "Add idle events (untriggered): %d\n", event_mask);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
client = mpd_clients;
|
||||||
|
while (client)
|
||||||
|
{
|
||||||
|
client->events |= event_mask;
|
||||||
|
if (client->is_idle)
|
||||||
|
{
|
||||||
|
client->events &= client->idle_events;
|
||||||
|
}
|
||||||
|
client = client->next;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mpd_notify_idle_client(struct mpd_client_ctx *client_ctx, short events)
|
mpd_notify_idle_client(struct mpd_client_ctx *client_ctx, short events)
|
||||||
{
|
{
|
||||||
@ -4782,6 +5088,9 @@ mpd_notify_idle_client(struct mpd_client_ctx *client_ctx, short events)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in case mpd_add_idle_events has added any events
|
||||||
|
events |= client_ctx->events;
|
||||||
|
|
||||||
if (!(client_ctx->idle_events & events))
|
if (!(client_ctx->idle_events & events))
|
||||||
{
|
{
|
||||||
DPRINTF(E_DBG, L_MPD, "Client not listening for events: %d\n", events);
|
DPRINTF(E_DBG, L_MPD, "Client not listening for events: %d\n", events);
|
||||||
@ -4792,10 +5101,10 @@ mpd_notify_idle_client(struct mpd_client_ctx *client_ctx, short events)
|
|||||||
evbuffer_add(client_ctx->evbuffer, "changed: database\n", 18);
|
evbuffer_add(client_ctx->evbuffer, "changed: database\n", 18);
|
||||||
if (events & LISTENER_UPDATE)
|
if (events & LISTENER_UPDATE)
|
||||||
evbuffer_add(client_ctx->evbuffer, "changed: update\n", 16);
|
evbuffer_add(client_ctx->evbuffer, "changed: update\n", 16);
|
||||||
if (events & LISTENER_PLAYER)
|
|
||||||
evbuffer_add(client_ctx->evbuffer, "changed: player\n", 16);
|
|
||||||
if (events & LISTENER_QUEUE)
|
if (events & LISTENER_QUEUE)
|
||||||
evbuffer_add(client_ctx->evbuffer, "changed: playlist\n", 18);
|
evbuffer_add(client_ctx->evbuffer, "changed: playlist\n", 18);
|
||||||
|
if (events & LISTENER_PLAYER)
|
||||||
|
evbuffer_add(client_ctx->evbuffer, "changed: player\n", 16);
|
||||||
if (events & LISTENER_VOLUME)
|
if (events & LISTENER_VOLUME)
|
||||||
evbuffer_add(client_ctx->evbuffer, "changed: mixer\n", 15);
|
evbuffer_add(client_ctx->evbuffer, "changed: mixer\n", 15);
|
||||||
if (events & LISTENER_SPEAKER)
|
if (events & LISTENER_SPEAKER)
|
||||||
@ -4804,6 +5113,8 @@ mpd_notify_idle_client(struct mpd_client_ctx *client_ctx, short events)
|
|||||||
evbuffer_add(client_ctx->evbuffer, "changed: options\n", 17);
|
evbuffer_add(client_ctx->evbuffer, "changed: options\n", 17);
|
||||||
if (events & LISTENER_STORED_PLAYLIST)
|
if (events & LISTENER_STORED_PLAYLIST)
|
||||||
evbuffer_add(client_ctx->evbuffer, "changed: stored_playlist\n", 25);
|
evbuffer_add(client_ctx->evbuffer, "changed: stored_playlist\n", 25);
|
||||||
|
if (events & LISTENER_STICKER)
|
||||||
|
evbuffer_add(client_ctx->evbuffer, "changed: sticker\n", 17);
|
||||||
|
|
||||||
evbuffer_add(client_ctx->evbuffer, "OK\n", 3);
|
evbuffer_add(client_ctx->evbuffer, "OK\n", 3);
|
||||||
|
|
||||||
@ -4843,12 +5154,21 @@ static void
|
|||||||
mpd_listener_cb(short event_mask)
|
mpd_listener_cb(short event_mask)
|
||||||
{
|
{
|
||||||
short *ptr;
|
short *ptr;
|
||||||
|
pthread_t current_thread = pthread_self();
|
||||||
|
|
||||||
|
if (pthread_equal(current_thread, tid_mpd))
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
DPRINTF(E_DBG, L_MPD, "Immediate listener callback called with event type %d.\n", event_mask);
|
||||||
|
mpd_notify_idle(&event_mask, &ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ptr = (short *)malloc(sizeof(short));
|
ptr = (short *)malloc(sizeof(short));
|
||||||
*ptr = event_mask;
|
*ptr = event_mask;
|
||||||
|
DPRINTF(E_DBG, L_MPD, "Asynchronous listener callback called with event type %d.\n", event_mask);
|
||||||
DPRINTF(E_DBG, L_MPD, "Listener callback called with event type %d.\n", event_mask);
|
|
||||||
commands_exec_async(cmdbase, mpd_notify_idle, ptr);
|
commands_exec_async(cmdbase, mpd_notify_idle, ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5116,7 +5436,7 @@ int mpd_init(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
mpd_clients = NULL;
|
mpd_clients = NULL;
|
||||||
listener_add(mpd_listener_cb, LISTENER_PLAYER | LISTENER_QUEUE | LISTENER_VOLUME | LISTENER_SPEAKER | LISTENER_OPTIONS | LISTENER_DATABASE | LISTENER_UPDATE | LISTENER_STORED_PLAYLIST);
|
listener_add(mpd_listener_cb, ALL_IDLE_LISTENER_EVENTS);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user