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
24 #include <sys/select.h>
35 #include "configuration.h"
40 /* TODO: a more comprehensive test */
42 static fd_set rfd, wfd;
44 static disorder_eclient *clients[1024];
46 static disorder_eclient *c;
50 static const char *modes[] = { "none", "read", "write", "read write" };
52 static void cb_comms_error(void *u, const char *msg) {
53 assert(u == &u_value);
54 fprintf(stderr, "! comms error: %s\n", msg);
57 static void cb_protocol_error(void *u,
58 void attribute((unused)) *v,
59 int attribute((unused)) code,
61 assert(u == &u_value);
62 fprintf(stderr, "! protocol error: %s\n", msg);
65 static void cb_poll(void *u, disorder_eclient *c_, int fd, unsigned mode) {
66 assert(u == &u_value);
68 assert(fd < 1024); /* bodge */
69 fprintf(stderr, " poll callback %d %s\n", fd, modes[mode]);
70 if(mode & DISORDER_POLL_READ)
74 if(mode & DISORDER_POLL_WRITE)
78 clients[fd] = mode ? c_ : 0;
79 if(fd > maxfd) maxfd = fd;
82 static void cb_report(void attribute((unused)) *u,
83 const char attribute((unused)) *msg) {
86 static const disorder_eclient_callbacks callbacks = {
93 /* cheap plastic event loop */
94 static void loop(void) {
98 fd_set r = rfd, w = wfd;
99 n = select(maxfd + 1, &r, &w, 0, 0);
101 if(errno == EINTR) continue;
102 fatal(errno, "select");
104 for(n = 0; n <= maxfd; ++n)
105 if(clients[n] && (FD_ISSET(n, &r) || FD_ISSET(n, &w)))
106 disorder_eclient_polled(clients[n],
107 ((FD_ISSET(n, &r) ? DISORDER_POLL_READ : 0)
108 |(FD_ISSET(n, &w) ? DISORDER_POLL_WRITE : 0)));
113 static void done(void) {
115 disorder_eclient_close(c);
119 static void play_completed(void *v) {
121 printf("* played: %s\n", *tracks);
124 if(disorder_eclient_play(c, *tracks, play_completed, tracks))
130 static void version_completed(void *v, const char *value) {
131 printf("* version: %s\n", value);
134 if(disorder_eclient_play(c, *tracks, play_completed, tracks))
141 /* TODO: de-dupe with disorder.c */
142 static void print_queue_entry(const struct queue_entry *q) {
143 if(q->track) xprintf("track %s\n", nullcheck(utf82mb(q->track)));
144 if(q->id) xprintf(" id %s\n", nullcheck(utf82mb(q->id)));
145 if(q->submitter) xprintf(" submitted by %s at %s",
146 nullcheck(utf82mb(q->submitter)), ctime(&q->when));
147 if(q->played) xprintf(" played at %s", ctime(&q->played));
148 if(q->state == playing_started
149 || q->state == playing_paused) xprintf(" %lds so far", q->sofar);
150 else if(q->expected) xprintf(" might start at %s", ctime(&q->expected));
151 if(q->scratched) xprintf(" scratched by %s\n",
152 nullcheck(utf82mb(q->scratched)));
153 else xprintf(" %s\n", playing_states[q->state]);
154 if(q->wstat) xprintf(" %s\n", wstat(q->wstat));
157 static void recent_completed(void *v, struct queue_entry *q) {
159 for(; q; q = q->next)
160 print_queue_entry(q);
161 if(disorder_eclient_version(c, version_completed, (void *)"")) exit(1);
164 int main(int argc, char **argv) {
167 debugging = 0; /* turn on for even more verbosity */
168 if(config_read(0)) fatal(0, "config_read failed");
170 c = disorder_eclient_new(&callbacks, &u_value);
172 /* stack up several version commands to test pipelining */
173 if(disorder_eclient_version(c, version_completed, 0)) exit(1);
174 if(disorder_eclient_version(c, version_completed, 0)) exit(1);
175 if(disorder_eclient_version(c, version_completed, 0)) exit(1);
176 if(disorder_eclient_version(c, version_completed, 0)) exit(1);
177 if(disorder_eclient_version(c, version_completed, 0)) exit(1);
178 if(disorder_eclient_recent(c, recent_completed, 0)) exit(1);