Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "acd.h"
2
 
3
static int
4
iscmd(char *s, char *cmd)
5
{
6
	int len;
7
 
8
	len = strlen(cmd);
9
	return strncmp(s, cmd, len)==0 && (s[len]=='\0' || s[len]==' ' || s[len]=='\t' || s[len]=='\n');
10
}
11
 
12
static char*
13
skip(char *s, char *cmd)
14
{
15
	s += strlen(cmd);
16
	while(*s==' ' || *s=='\t' || *s=='\n')
17
		s++;
18
	return s;
19
}
20
 
21
//#define PLAYSTRING "/^[0-9:]+>"
22
//#define PLAYSTRINGSPACE "/^[0-9:]+> ?"
23
//#define INITSTRING "0:00> "
24
 
25
#define INITSTRING "> "
26
#define PLAYSTRING "/^>"
27
#define PLAYSTRINGSPACE "/^> ?"
28
 
29
/*
30
 * find the playing string, leave in addr
31
 * if q0, q1 are non-nil, set them to the addr of the string.
32
 */
33
int
34
findplay(Window *w, char *s, ulong *q0, ulong *q1)
35
{
36
	char xbuf[25];
37
	if(w->data < 0)
38
		w->data = winopenfile(w, "data");
39
 
40
	if(!winsetaddr(w, "#0", 1) || !winsetaddr(w, s, 1))
41
		return 0;
42
 
43
	seek(w->addr, 0, 0);
44
	if(read(w->addr, xbuf, 24) != 24)
45
		return 0;
46
 
47
	xbuf[24] = 0;
48
	if(q0)
49
		*q0 = atoi(xbuf);
50
	if(q1)
51
		*q1 = atoi(xbuf+12);
52
 
53
	return 1;
54
}
55
 
56
/*
57
 * find the playing string and replace the time
58
 */
59
int
60
setplaytime(Window *w, char *new)
61
{
62
	char buf[40];
63
	ulong q0, q1;
64
 
65
return 1;
66
	if(!findplay(w, PLAYSTRING, &q0, &q1))
67
		return 0;
68
 
69
	q1--;	/* > */
70
	sprint(buf, "#%lud,#%lud", q0, q1);
71
	DPRINT(2, "setaddr %s\n", buf);
72
	if(!winsetaddr(w, buf, 1))
73
		return 0;
74
 
75
	if(write(w->data, new, strlen(new)) != strlen(new))
76
		return 0;
77
 
78
	return 1;
79
}
80
 
81
/*
82
 * find the playing string, and remove it.
83
 * return the string at the beginning of hte next line in buf
84
 * (presumably a track number).
85
 */
86
static int
87
unmarkplay(Window *w, char *buf, int n, ulong *q0, ulong *q1, ulong *qbegin)
88
{
89
	char xbuf[24];
90
 
91
	if(!findplay(w, PLAYSTRINGSPACE, q0, q1))
92
		return 0;
93
 
94
	if(write(w->data, "", 0) < 0 || !winsetaddr(w, "+1+#0", 1))
95
		return 0;
96
 
97
	if(qbegin) {
98
		seek(w->addr, 0, 0);
99
		if(read(w->addr, xbuf, 24) != 24)
100
			return 0;
101
		*qbegin = atoi(xbuf);
102
	}
103
 
104
	if(buf) {
105
		if((n = read(w->data, buf, n-1)) < 0)
106
			return 0;
107
 
108
		buf[n] = '\0';
109
	}
110
 
111
	return 1;
112
}
113
 
114
int
115
markplay(Window *w, ulong q0)
116
{
117
	char buf[20];
118
 
119
	if(w->data < 0)
120
		w->data = winopenfile(w, "data");
121
 
122
	sprint(buf, "#%lud", q0);
123
	DPRINT(2, "addr %s\n", buf);
124
	if(!winsetaddr(w, buf, 1) || !winsetaddr(w, "-0", 1))
125
		return 0;
126
	if(write(w->data, INITSTRING, strlen(INITSTRING)) != strlen(INITSTRING))
127
		return 0;
128
	return 1;
129
}
130
 
131
/* return 1 if handled, 0 otherwise */
132
int
133
cdcommand(Window *w, Drive *d, char *s)
134
{
135
	s = skip(s, "");
136
 
137
	if(iscmd(s, "Del")){
138
		if(windel(w, 0))
139
			threadexitsall(nil);
140
		return 1;
141
	}
142
	if(iscmd(s, "Stop")){
143
		unmarkplay(w, nil, 0, nil, nil, nil);
144
		stop(d);
145
		return 1;
146
	}
147
	if(iscmd(s, "Eject")){
148
		unmarkplay(w, nil, 0, nil, nil, nil);
149
		eject(d);
150
		return 1;
151
	}
152
	if(iscmd(s, "Ingest")){
153
		unmarkplay(w, nil, 0, nil, nil, nil);
154
		ingest(d);
155
		return 1;
156
	}
157
	if(iscmd(s, "Pause")){
158
		pause(d);
159
		return 1;
160
	}
161
	if(iscmd(s, "Resume")){
162
		resume(d);
163
		return 1;
164
	}
165
	return 0;
166
}
167
 
168
void
169
drawtoc(Window *w, Drive *d, Toc *t)
170
{
171
	int i, playing;
172
 
173
	if(w->data < 0)
174
		w->data = winopenfile(w, "data");
175
	if(!winsetaddr(w, ",", 1))
176
		return;
177
 
178
	fprint(w->data, "Title\n\n");
179
	playing = -1;
180
	if(d->status.state == Splaying || d->status.state == Spaused)
181
		playing = d->status.track-t->track0;
182
 
183
	for(i=0; i<t->ntrack; i++)
184
		fprint(w->data, "%s%d/ Track %d\n", i==playing ? "> " : "", i+1, i+1);
185
	fprint(w->data, "");
186
}
187
 
188
void
189
redrawtoc(Window *w, Toc *t)
190
{
191
	int i;
192
	char old[50];
193
 
194
	if(w->data < 0)
195
		w->data = winopenfile(w, "data");
196
	if(t->title) {
197
		if(winsetaddr(w, "/Title", 1))
198
			write(w->data, t->title, strlen(t->title));
199
	}
200
	for(i=0; i<t->ntrack; i++) {
201
		if(t->track[i].title) {
202
			sprint(old, "/Track %d", i+1);
203
			if(winsetaddr(w, old, 1))
204
				write(w->data, t->track[i].title, strlen(t->track[i].title));
205
		}
206
	}
207
}
208
 
209
void
210
advancetrack(Drive *d, Window *w)
211
{
212
	int n;
213
	ulong q0, q1, qnext;
214
	char buf[20];
215
 
216
	q0 = q1 = 0;
217
	if(!unmarkplay(w, buf, sizeof(buf), &q0, &q1, &qnext)) {
218
		DPRINT(2, "unmark: %r\n");
219
		return;
220
	}
221
 
222
	DPRINT(2, "buf: %s\n", buf);
223
	if(strncmp(buf, "repeat", 6) == 0) {
224
		if(!winsetaddr(w, "#0", 1) || !findplay(w, "/^[0-9]+\\/", &qnext, nil)) {
225
			DPRINT(2, "set/find: %r\n");
226
			return;
227
		}
228
		if(w->data < 0)
229
			w->data = winopenfile(w, "data");
230
		if((n = read(w->data, buf, sizeof(buf)-1)) <= 0) {
231
			DPRINT(2, "read %d: %r\n", n);
232
			return;
233
		}
234
		buf[n] = 0;
235
		DPRINT(2, "buf: %s\n", buf);
236
	}
237
 
238
	if((n = atoi(buf)) == 0)
239
		return;
240
 
241
	if(!markplay(w, qnext))
242
		DPRINT(2, "err: %r");
243
 
244
	playtrack(d, n-1, n-1);
245
}
246
 
247
void
248
acmeevent(Drive *d, Window *w, Event *e)
249
{
250
	Event *ea, *e2, *eq;
251
	char *s, *t, *buf;
252
	int n, na;
253
	ulong q0, q1;
254
 
255
	switch(e->c1){	/* origin of action */
256
	default:
257
	Unknown:
258
		fprint(2, "unknown message %c%c\n", e->c1, e->c2);
259
		break;
260
 
261
	case 'E':	/* write to body or tag; can't affect us */
262
		break;
263
 
264
	case 'F':	/* generated by our actions; ignore */
265
		break;
266
 
267
	case 'K':	/* type away; we don't care */
268
		break;
269
 
270
	case 'M':	/* mouse event */
271
		switch(e->c2){		/* type of action */
272
		case 'x':	/* mouse: button 2 in tag */
273
		case 'X':	/* mouse: button 2 in body */
274
			ea = nil;
275
		//	e2 = nil;
276
			s = e->b;
277
			if(e->flag & 2){	/* null string with non-null expansion */
278
				e2 = recvp(w->cevent);
279
				if(e->nb==0)
280
					s = e2->b;
281
			}
282
			if(e->flag & 8){	/* chorded argument */
283
				ea = recvp(w->cevent);	/* argument */
284
				na = ea->nb;
285
				recvp(w->cevent);		/* ignore origin */
286
			}else
287
				na = 0;
288
 
289
			/* append chorded arguments */
290
			if(na){
291
				t = emalloc(strlen(s)+1+na+1);
292
				sprint(t, "%s %s", s, ea->b);
293
				s = t;
294
			}
295
			/* if it's a known command, do it */
296
			/* if it's a long message, it can't be for us anyway */
297
			DPRINT(2, "exec: %s\n", s);
298
			if(!cdcommand(w, d, s))	/* send it back */
299
				winwriteevent(w, e);
300
			if(na)
301
				free(s);
302
			break;
303
 
304
		case 'l':	/* mouse: button 3 in tag */
305
		case 'L':	/* mouse: button 3 in body */
306
		//	buf = nil;
307
			eq = e;
308
			if(e->flag & 2){
309
				e2 = recvp(w->cevent);
310
				eq = e2;
311
			}
312
			s = eq->b;
313
			if(eq->q1>eq->q0 && eq->nb==0){
314
				buf = emalloc((eq->q1-eq->q0)*UTFmax+1);
315
				winread(w, eq->q0, eq->q1, buf);
316
				s = buf;
317
			}
318
			DPRINT(2, "load %s\n", s);
319
			if((n = atoi(s)) != 0) {
320
				DPRINT(2, "mark %d\n", n);
321
				q0 = q1 = 0;
322
				unmarkplay(w, nil, 0, &q0, &q1, nil);
323
 
324
				/* adjust eq->q* for deletion */
325
				if(eq->q0 > q1) {
326
					eq->q0 -= (q1-q0);
327
					eq->q1 -= (q1-q0);
328
				}
329
				if(!markplay(w, eq->q0))
330
					DPRINT(2, "err: %r\n");
331
 
332
				playtrack(d, n-1, n-1);
333
			} else
334
				winwriteevent(w, e);
335
			break;
336
 
337
		case 'i':	/* mouse: text inserted in tag */
338
		case 'I':	/* mouse: text inserted in body */
339
		case 'd':	/* mouse: text deleted from tag */
340
		case 'D':	/* mouse: text deleted from body */
341
			break;
342
 
343
		default:
344
			goto Unknown;
345
		}
346
	}
347
}