2 (c) 2003-2009 The Music Player Daemon Project
3 This project's homepage is: http://www.musicpd.org
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 - Neither the name of the Music Player Daemon nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <mpd/connection.h>
38 #include <mpd/response.h>
45 static const char *const idle_names
[] = {
58 mpd_idle_name(enum mpd_idle idle
)
60 for (unsigned i
= 0; idle_names
[i
] != NULL
; ++i
)
61 if (idle
== (enum mpd_idle
)(1 << i
))
68 mpd_idle_name_parse(const char *name
)
72 for (unsigned i
= 0; idle_names
[i
] != NULL
; ++i
)
73 if (strcmp(name
, idle_names
[i
]) == 0)
80 mpd_idle_parse_pair(const struct mpd_pair
*pair
)
84 if (strcmp(pair
->name
, "changed") != 0)
87 return mpd_idle_name_parse(pair
->value
);
91 mpd_recv_idle(struct mpd_connection
*connection
)
93 enum mpd_idle flags
= 0;
94 struct mpd_pair
*pair
;
95 struct timeval old_timeout
;
97 assert(connection
!= NULL
);
99 /* make sure that the output buffer is empty before we turn
100 off the timeout - this is important because we want to
101 detect a send failure more quickly */
102 if (!mpd_flush(connection
))
105 /* temporarily disable the connection timeout */
106 old_timeout
= connection
->timeout
;
107 connection
->timeout
= (struct timeval
){
112 while ((pair
= mpd_recv_pair(connection
)) != NULL
) {
113 flags
|= mpd_idle_parse_pair(pair
);
115 mpd_return_pair(connection
, pair
);
118 /* re-enable timeout */
119 connection
->timeout
= old_timeout
;
125 mpd_send_idle(struct mpd_connection
*connection
)
127 return mpd_send_command(connection
, "idle", NULL
);
131 mpd_send_idle_mask(struct mpd_connection
*connection
, enum mpd_idle mask
)
133 /* this buffer is large enough even for the full mask */
134 char buffer
[128] = "idle";
138 if (mpd_error_is_defined(&connection
->error
))
141 for (unsigned i
= 0; idle_names
[i
] != NULL
; ++i
) {
142 if (mask
& (1 << i
)) {
145 strcat(buffer
, idle_names
[i
]);
150 /* the client expects that all flags are supported,
151 because he might block forever if an event is not
152 delivered as expected */
153 mpd_error_code(&connection
->error
, MPD_ERROR_ARGUMENT
);
154 mpd_error_printf(&connection
->error
,
155 "Unsupported idle flags: 0x%x", mask
);
159 return mpd_send_command(connection
, buffer
, NULL
);
163 mpd_send_noidle(struct mpd_connection
*connection
)
165 return mpd_send_command(connection
, "noidle", NULL
);
169 mpd_run_idle(struct mpd_connection
*connection
)
173 if (!mpd_run_check(connection
) || !mpd_send_idle(connection
))
176 flags
= mpd_recv_idle(connection
);
177 if (!mpd_response_finish(connection
))
184 mpd_run_idle_mask(struct mpd_connection
*connection
, enum mpd_idle mask
)
188 if (!mpd_run_check(connection
) ||
189 !mpd_send_idle_mask(connection
, mask
))
192 flags
= mpd_recv_idle(connection
);
193 if (!mpd_response_finish(connection
))