chiark / gitweb /
more control state fiddling, starts nicely when server down now
[disorder] / disobedience / log.c
CommitLineData
10e226b3
RK
1/*
2 * This file is part of DisOrder.
3 * Copyright (C) 2006, 2007 Richard Kettlewell
4 *
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.
9 *
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.
14 *
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
18 * USA
19 */
20
21#include "disobedience.h"
22
186f896b 23/* State monitoring -------------------------------------------------------- */
10e226b3
RK
24
25static void log_connected(void *v);
26static void log_completed(void *v, const char *track);
27static void log_failed(void *v, const char *track, const char *status);
28static void log_moved(void *v, const char *user);
29static void log_playing(void *v, const char *track, const char *user);
30static void log_queue(void *v, struct queue_entry *q);
31static void log_recent_added(void *v, struct queue_entry *q);
32static void log_recent_removed(void *v, const char *id);
33static void log_removed(void *v, const char *id, const char *user);
34static void log_scratched(void *v, const char *track, const char *user);
35static void log_state(void *v, unsigned long state);
36static void log_volume(void *v, int l, int r);
37
38/** @brief Callbacks for server state monitoring */
39const disorder_eclient_log_callbacks log_callbacks = {
40 log_connected,
41 log_completed,
42 log_failed,
43 log_moved,
44 log_playing,
45 log_queue,
46 log_recent_added,
47 log_recent_removed,
48 log_removed,
49 log_scratched,
50 log_state,
51 log_volume
52};
53
186f896b
RK
54struct monitor {
55 struct monitor *next;
56 unsigned long mask;
57 monitor_callback *callback;
58 void *u;
59};
60
61static struct monitor *monitors;
10e226b3
RK
62
63void all_update(void) {
64 playing_update();
65 queue_update();
66 recent_update();
6d1302f0 67 volume_update();
10e226b3
RK
68}
69
70static void log_connected(void attribute((unused)) *v) {
10e226b3
RK
71 /* Don't know what we might have missed while disconnected so update
72 * everything. We get this at startup too and this is how we do the initial
73 * state fetch. */
74 all_update();
10e226b3
RK
75}
76
77static void log_completed(void attribute((unused)) *v,
78 const char attribute((unused)) *track) {
79 playing = 0;
80 playing_update();
10e226b3
RK
81}
82
83static void log_failed(void attribute((unused)) *v,
84 const char attribute((unused)) *track,
85 const char attribute((unused)) *status) {
86 playing = 0;
87 playing_update();
10e226b3
RK
88}
89
90static void log_moved(void attribute((unused)) *v,
91 const char attribute((unused)) *user) {
92 queue_update();
93}
94
95static void log_playing(void attribute((unused)) *v,
96 const char attribute((unused)) *track,
97 const char attribute((unused)) *user) {
98 playing = 1;
99 playing_update();
10e226b3
RK
100 /* we get a log_removed() anyway so we don't need to update_queue() from
101 * here */
102}
103
104static void log_queue(void attribute((unused)) *v,
105 struct queue_entry attribute((unused)) *q) {
106 queue_update();
107}
108
109static void log_recent_added(void attribute((unused)) *v,
110 struct queue_entry attribute((unused)) *q) {
111 recent_update();
112}
113
114static void log_recent_removed(void attribute((unused)) *v,
115 const char attribute((unused)) *id) {
116 /* nothing - log_recent_added() will trigger the relevant update */
117}
118
119static void log_removed(void attribute((unused)) *v,
120 const char attribute((unused)) *id,
121 const char attribute((unused)) *user) {
122 queue_update();
123}
124
125static void log_scratched(void attribute((unused)) *v,
126 const char attribute((unused)) *track,
127 const char attribute((unused)) *user) {
128 playing = 0;
129 playing_update();
10e226b3
RK
130}
131
132static void log_state(void attribute((unused)) *v,
133 unsigned long state) {
186f896b 134 const struct monitor *m;
6d1302f0
RK
135 unsigned long changes = state ^ last_state;
136 static int first = 1;
137
138 if(first) {
139 changes = -1UL;
140 first = 0;
141 }
142 D(("log_state old=%s new=%s changed=%s",
143 disorder_eclient_interpret_state(last_state),
144 disorder_eclient_interpret_state(state),
145 disorder_eclient_interpret_state(changes)));
00959300 146 last_state = state;
186f896b
RK
147 /* Tell anything that cares about the state change */
148 for(m = monitors; m; m = m->next) {
00959300
RK
149 if(changes & m->mask)
150 m->callback(m->u);
186f896b 151 }
10e226b3
RK
152 /* If the track is paused or resume then the currently playing track is
153 * refetched so that we can continue to correctly calculate the played so-far
154 * field */
155 playing_update();
156}
157
158static void log_volume(void attribute((unused)) *v,
159 int l, int r) {
160 if(volume_l != l || volume_r != r) {
161 volume_l = l;
162 volume_r = r;
6d1302f0 163 volume_update();
10e226b3
RK
164 }
165}
166
186f896b
RK
167void register_monitor(monitor_callback *callback,
168 void *u,
169 unsigned long mask) {
170 struct monitor *m = xmalloc(sizeof *m);
171
172 m->next = monitors;
173 m->mask = mask;
174 m->callback = callback;
175 m->u = u;
176 monitors = m;
177}
178
10e226b3
RK
179/*
180Local Variables:
181c-basic-offset:2
182comment-column:40
183fill-column:79
184indent-tabs-mode:nil
185End:
186*/