2 * This file is part of DisOrder.
3 * Copyright (C) 2006 Richard Kettlewell
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 #include <sys/select.h>
31 #include "configuration.h"
36 /* TODO: a more comprehensive test */
38 static fd_set rfd
, wfd
;
40 static disorder_eclient
*clients
[1024];
42 static disorder_eclient
*c
;
46 static const char *modes
[] = { "none", "read", "write", "read write" };
48 static void cb_comms_error(void *u
, const char *msg
) {
49 assert(u
== &u_value
);
50 fprintf(stderr
, "! comms error: %s\n", msg
);
53 static void cb_protocol_error(void *u
,
54 void attribute((unused
)) *v
,
55 int attribute((unused
)) code
,
57 assert(u
== &u_value
);
58 fprintf(stderr
, "! protocol error: %s\n", msg
);
61 static void cb_poll(void *u
, disorder_eclient
*c_
, int fd
, unsigned mode
) {
62 assert(u
== &u_value
);
64 assert(fd
< 1024); /* bodge */
65 fprintf(stderr
, " poll callback %d %s\n", fd
, modes
[mode
]);
66 if(mode
& DISORDER_POLL_READ
)
70 if(mode
& DISORDER_POLL_WRITE
)
74 clients
[fd
] = mode ? c_
: 0;
75 if(fd
> maxfd
) maxfd
= fd
;
78 static void cb_report(void attribute((unused
)) *u
,
79 const char attribute((unused
)) *msg
) {
82 static const disorder_eclient_callbacks callbacks
= {
89 /* cheap plastic event loop */
90 static void loop(void) {
94 fd_set r
= rfd
, w
= wfd
;
95 n
= select(maxfd
+ 1, &r
, &w
, 0, 0);
97 if(errno
== EINTR
) continue;
98 fatal(errno
, "select");
100 for(n
= 0; n
<= maxfd
; ++n
)
101 if(clients
[n
] && (FD_ISSET(n
, &r
) || FD_ISSET(n
, &w
)))
102 disorder_eclient_polled(clients
[n
],
103 ((FD_ISSET(n
, &r
) ? DISORDER_POLL_READ
: 0)
104 |(FD_ISSET(n
, &w
) ? DISORDER_POLL_WRITE
: 0)));
109 static void done(void) {
111 disorder_eclient_close(c
);
115 static void play_completed(void *v
) {
117 printf("* played: %s\n", *tracks
);
120 if(disorder_eclient_play(c
, *tracks
, play_completed
, tracks
))
126 static void version_completed(void *v
, const char *value
) {
127 printf("* version: %s\n", value
);
130 if(disorder_eclient_play(c
, *tracks
, play_completed
, tracks
))
137 /* TODO: de-dupe with disorder.c */
138 static void print_queue_entry(const struct queue_entry
*q
) {
139 if(q
->track
) xprintf("track %s\n", nullcheck(utf82mb(q
->track
)));
140 if(q
->id
) xprintf(" id %s\n", nullcheck(utf82mb(q
->id
)));
141 if(q
->submitter
) xprintf(" submitted by %s at %s",
142 nullcheck(utf82mb(q
->submitter
)), ctime(&q
->when
));
143 if(q
->played
) xprintf(" played at %s", ctime(&q
->played
));
144 if(q
->state
== playing_started
145 || q
->state
== playing_paused
) xprintf(" %lds so far", q
->sofar
);
146 else if(q
->expected
) xprintf(" might start at %s", ctime(&q
->expected
));
147 if(q
->scratched
) xprintf(" scratched by %s\n",
148 nullcheck(utf82mb(q
->scratched
)));
149 else xprintf(" %s\n", playing_states
[q
->state
]);
150 if(q
->wstat
) xprintf(" %s\n", wstat(q
->wstat
));
153 static void recent_completed(void *v
, struct queue_entry
*q
) {
155 for(; q
; q
= q
->next
)
156 print_queue_entry(q
);
157 if(disorder_eclient_version(c
, version_completed
, (void *)"")) exit(1);
160 int main(int argc
, char **argv
) {
163 debugging
= 0; /* turn on for even more verbosity */
164 if(config_read(0)) fatal(0, "config_read failed");
166 c
= disorder_eclient_new(&callbacks
, &u_value
);
168 /* stack up several version commands to test pipelining */
169 if(disorder_eclient_version(c
, version_completed
, 0)) exit(1);
170 if(disorder_eclient_version(c
, version_completed
, 0)) exit(1);
171 if(disorder_eclient_version(c
, version_completed
, 0)) exit(1);
172 if(disorder_eclient_version(c
, version_completed
, 0)) exit(1);
173 if(disorder_eclient_version(c
, version_completed
, 0)) exit(1);
174 if(disorder_eclient_recent(c
, recent_completed
, 0)) exit(1);