aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client.c29
-rw-r--r--src/client.h2
-rw-r--r--src/command.c25
-rw-r--r--src/idle.c18
-rw-r--r--src/idle.h6
5 files changed, 60 insertions, 20 deletions
diff --git a/src/client.c b/src/client.c
index ee984641e..fd55b31a8 100644
--- a/src/client.c
+++ b/src/client.c
@@ -91,6 +91,9 @@ struct client {
/** idle flags pending on this client, to be sent as soon as
the client enters "idle" */
unsigned idle_flags;
+
+ /** idle flags that the client wants to receive */
+ unsigned idle_subscriptions;
};
static LIST_HEAD(clients);
@@ -766,16 +769,6 @@ mpd_fprintf void client_printf(struct client *client, const char *fmt, ...)
va_end(args);
}
-static const char *const idle_names[] = {
- "database",
- "stored_playlist",
- "playlist",
- "player",
- "mixer",
- "output",
- "options",
-};
-
/**
* Send "idle" response to this client.
*/
@@ -783,6 +776,7 @@ static void
client_idle_notify(struct client *client)
{
unsigned flags, i;
+ const char *const* idle_names;
assert(client->idle_waiting);
assert(client->idle_flags != 0);
@@ -791,10 +785,9 @@ client_idle_notify(struct client *client)
client->idle_flags = 0;
client->idle_waiting = false;
- for (i = 0; i < sizeof(idle_names) / sizeof(idle_names[0]); ++i) {
- assert(idle_names[i] != NULL);
-
- if (flags & (1 << i))
+ idle_names = idle_get_names();
+ for (i = 0; idle_names[i]; ++i) {
+ if (flags & (1 << i) & client->idle_subscriptions)
client_printf(client, "changed: %s\n",
idle_names[i]);
}
@@ -814,20 +807,22 @@ void client_manager_idle_add(unsigned flags)
continue;
client->idle_flags |= flags;
- if (client->idle_waiting) {
+ if (client->idle_waiting
+ && (client->idle_flags & client->idle_subscriptions)) {
client_idle_notify(client);
client_write_output(client);
}
}
}
-bool client_idle_wait(struct client *client)
+bool client_idle_wait(struct client *client, unsigned flags)
{
assert(!client->idle_waiting);
client->idle_waiting = true;
+ client->idle_subscriptions = flags;
- if (client->idle_flags != 0) {
+ if (client->idle_flags & client->idle_subscriptions) {
client_idle_notify(client);
return true;
} else
diff --git a/src/client.h b/src/client.h
index e6661e249..9c7031820 100644
--- a/src/client.h
+++ b/src/client.h
@@ -78,6 +78,6 @@ void client_manager_idle_add(unsigned flags);
* sent immediately and "true" is returned". If no, it puts the
* client into waiting mode and returns false.
*/
-bool client_idle_wait(struct client *client);
+bool client_idle_wait(struct client *client, unsigned flags);
#endif
diff --git a/src/command.c b/src/command.c
index dc71f1d1a..6a9489d92 100644
--- a/src/command.c
+++ b/src/command.c
@@ -39,6 +39,7 @@
#include "tag_print.h"
#include "path.h"
#include "os_compat.h"
+#include "idle.h"
#define COMMAND_STATUS_VOLUME "volume"
#define COMMAND_STATUS_STATE "state"
@@ -1253,8 +1254,28 @@ static enum command_return
handle_idle(struct client *client,
mpd_unused int argc, mpd_unused char *argv[])
{
+ unsigned flags = 0, j;
+ int i;
+ const char *const* idle_names;
+
+ idle_names = idle_get_names();
+ for (i = 1; i < argc; ++i) {
+ if (!argv[i])
+ continue;
+
+ for (j = 0; idle_names[j]; ++j) {
+ if (!strcasecmp(argv[i], idle_names[j])) {
+ flags |= (1 << j);
+ }
+ }
+ }
+
+ /* No argument means that the client wants to receive everything */
+ if (flags == 0)
+ flags = ~0;
+
/* enable "idle" mode on this client */
- client_idle_wait(client);
+ client_idle_wait(client, flags);
/* return value is "1" so the caller won't print "OK" */
return 1;
@@ -1280,7 +1301,7 @@ static const struct command commands[] = {
{ "disableoutput", PERMISSION_ADMIN, 1, 1, handle_disableoutput },
{ "enableoutput", PERMISSION_ADMIN, 1, 1, handle_enableoutput },
{ "find", PERMISSION_READ, 2, -1, handle_find },
- { "idle", PERMISSION_READ, 0, 0, handle_idle },
+ { "idle", PERMISSION_READ, 0, -1, handle_idle },
{ "kill", PERMISSION_ADMIN, -1, -1, handle_kill },
{ "list", PERMISSION_READ, 1, -1, handle_list },
{ "listall", PERMISSION_READ, 0, 1, handle_listall },
diff --git a/src/idle.c b/src/idle.c
index c779d0a91..884086aae 100644
--- a/src/idle.c
+++ b/src/idle.c
@@ -30,6 +30,18 @@
static unsigned idle_flags;
static pthread_mutex_t idle_mutex = PTHREAD_MUTEX_INITIALIZER;
+static const char *const idle_names[] = {
+ "database",
+ "stored_playlist",
+ "playlist",
+ "player",
+ "mixer",
+ "output",
+ "options",
+ "elapsed",
+ NULL
+};
+
void
idle_add(unsigned flags)
{
@@ -54,3 +66,9 @@ idle_get(void)
return flags;
}
+
+const char*const*
+idle_get_names(void)
+{
+ return idle_names;
+}
diff --git a/src/idle.h b/src/idle.h
index 69756b153..5079f09db 100644
--- a/src/idle.h
+++ b/src/idle.h
@@ -61,4 +61,10 @@ idle_add(unsigned flags);
unsigned
idle_get(void);
+/**
+ * Get idle names
+ */
+const char*const*
+idle_get_names(void);
+
#endif