Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/acme/wiki/src/win.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "awiki.h"
2
 
3
Window*
4
newwindow(void)
5
{
6
	char buf[12];
7
	Window *w;
8
 
9
	w = emalloc(sizeof(Window));
10
	w->ctl = open("/mnt/wsys/new/ctl", ORDWR|OCEXEC);
11
	if(w->ctl<0 || read(w->ctl, buf, 12)!=12)
12
		error("can't open window ctl file: %r");
13
	ctlprint(w->ctl, "noscroll\n");
14
	w->id = atoi(buf);
15
	w->event = winopenfile(w, "event");
16
	w->addr = -1;	/* will be opened when needed */
17
	w->body = nil;
18
	w->data = -1;
19
	w->cevent = chancreate(sizeof(Event*), 0);
20
	if(w->cevent == nil)
21
		error("cevent is nil: %r");
22
	return w;
23
}
24
 
25
void
26
winsetdump(Window *w, char *dir, char *cmd)
27
{
28
	if(dir != nil)
29
		ctlprint(w->ctl, "dumpdir %s\n", dir);
30
	if(cmd != nil)
31
		ctlprint(w->ctl, "dump %s\n", cmd);
32
}
33
 
34
void
35
wineventproc(void *v)
36
{
37
	Window *w;
38
	int i;
39
 
40
	threadsetname("wineventproc");
41
	w = v;
42
	for(i=0; ; i++){
43
		if(i >= NEVENT)
44
			i = 0;
45
		wingetevent(w, &w->e[i]);
46
		sendp(w->cevent, &w->e[i]);
47
	}
48
}
49
 
50
int
51
winopenfile(Window *w, char *f)
52
{
53
	char buf[64];
54
	int fd;
55
 
56
	sprint(buf, "/mnt/wsys/%d/%s", w->id, f);
57
	fd = open(buf, ORDWR|OCEXEC);
58
	if(fd < 0)
59
		error("can't open window file %s: %r", f);
60
	return fd;
61
}
62
 
63
void
64
wintagwrite(Window *w, char *s, int n)
65
{
66
	int fd;
67
 
68
	fd = winopenfile(w, "tag");
69
	if(write(fd, s, n) != n)
70
		error("tag write: %r");
71
	close(fd);
72
}
73
 
74
void
75
winname(Window *w, char *s)
76
{
77
	ctlprint(w->ctl, "name %s\n", s);
78
}
79
 
80
void
81
winopenbody(Window *w, int mode)
82
{
83
	char buf[256];
84
 
85
	sprint(buf, "/mnt/wsys/%d/body", w->id);
86
	w->body = Bopen(buf, mode|OCEXEC);
87
	if(w->body == nil)
88
		error("can't open window body file: %r");
89
}
90
 
91
void
92
winclosebody(Window *w)
93
{
94
	if(w->body != nil){
95
		Bterm(w->body);
96
		w->body = nil;
97
	}
98
}
99
 
100
void
101
winwritebody(Window *w, char *s, int n)
102
{
103
	if(w->body == nil)
104
		winopenbody(w, OWRITE);
105
	if(Bwrite(w->body, s, n) != n)
106
		error("write error to window: %r");
107
}
108
 
109
int
110
wingetec(Window *w)
111
{
112
	if(w->nbuf == 0){
113
		w->nbuf = read(w->event, w->buf, sizeof w->buf);
114
		if(w->nbuf <= 0){
115
			/* probably because window has exited, and only called by wineventproc, so just shut down */
116
			threadexits(nil);
117
		}
118
		w->bufp = w->buf;
119
	}
120
	w->nbuf--;
121
	return *w->bufp++;
122
}
123
 
124
int
125
wingeten(Window *w)
126
{
127
	int n, c;
128
 
129
	n = 0;
130
	while('0'<=(c=wingetec(w)) && c<='9')
131
		n = n*10+(c-'0');
132
	if(c != ' ')
133
		error("event number syntax");
134
	return n;
135
}
136
 
137
int
138
wingeter(Window *w, char *buf, int *nb)
139
{
140
	Rune r;
141
	int n;
142
 
143
	r = wingetec(w);
144
	buf[0] = r;
145
	n = 1;
146
	if(r >= Runeself) {
147
		while(!fullrune(buf, n))
148
			buf[n++] = wingetec(w);
149
		chartorune(&r, buf);
150
	} 
151
	*nb = n;
152
	return r;
153
}
154
 
155
void
156
wingetevent(Window *w, Event *e)
157
{
158
	int i, nb;
159
 
160
	e->c1 = wingetec(w);
161
	e->c2 = wingetec(w);
162
	e->q0 = wingeten(w);
163
	e->q1 = wingeten(w);
164
	e->flag = wingeten(w);
165
	e->nr = wingeten(w);
166
	if(e->nr > EVENTSIZE)
167
		error("event string too long");
168
	e->nb = 0;
169
	for(i=0; i<e->nr; i++){
170
		e->r[i] = wingeter(w, e->b+e->nb, &nb);
171
		e->nb += nb;
172
	}
173
	e->r[e->nr] = 0;
174
	e->b[e->nb] = 0;
175
	if(wingetec(w) != '\n')
176
		error("event syntax error");
177
}
178
 
179
void
180
winwriteevent(Window *w, Event *e)
181
{
182
	fprint(w->event, "%c%c%d %d\n", e->c1, e->c2, e->q0, e->q1);
183
}
184
 
185
static int
186
nrunes(char *s, int nb)
187
{
188
	int i, n;
189
	Rune r;
190
 
191
	n = 0;
192
	for(i=0; i<nb; n++)
193
		i += chartorune(&r, s+i);
194
	return n;
195
}
196
 
197
void
198
winread(Window *w, uint q0, uint q1, char *data)
199
{
200
	int m, n, nr;
201
	char buf[256];
202
 
203
	if(w->addr < 0)
204
		w->addr = winopenfile(w, "addr");
205
	if(w->data < 0)
206
		w->data = winopenfile(w, "data");
207
	m = q0;
208
	while(m < q1){
209
		n = sprint(buf, "#%d", m);
210
		if(write(w->addr, buf, n) != n)
211
			error("error writing addr: %r");
212
		n = read(w->data, buf, sizeof buf);
213
		if(n <= 0)
214
			error("reading data: %r");
215
		nr = nrunes(buf, n);
216
		while(m+nr >q1){
217
			do; while(n>0 && (buf[--n]&0xC0)==0x80);
218
			--nr;
219
		}
220
		if(n == 0)
221
			break;
222
		memmove(data, buf, n);
223
		data += n;
224
		*data = 0;
225
		m += nr;
226
	}
227
}
228
 
229
void
230
windormant(Window *w)
231
{
232
	if(w->addr >= 0){
233
		close(w->addr);
234
		w->addr = -1;
235
	}
236
	if(w->body != nil){
237
		Bterm(w->body);
238
		w->body = nil;
239
	}
240
	if(w->data >= 0){
241
		close(w->data);
242
		w->data = -1;
243
	}
244
}
245
 
246
 
247
int
248
windel(Window *w, int sure)
249
{
250
	if(sure)
251
		write(w->ctl, "delete\n", 7);
252
	else if(write(w->ctl, "del\n", 4) != 4)
253
		return 0;
254
	/* event proc will die due to read error from event file */
255
	windormant(w);
256
	close(w->ctl);
257
	w->ctl = -1;
258
	close(w->event);
259
	w->event = -1;
260
	return 1;
261
}
262
 
263
void
264
winclean(Window *w)
265
{
266
	if(w->body)
267
		Bflush(w->body);
268
	ctlprint(w->ctl, "clean\n");
269
}
270
 
271
int
272
winisdirty(Window *w)
273
{
274
	char m;
275
 
276
	if (seek(w->ctl, 4*(11+1) + 10, 0) < 0)
277
		error("control file seek error: %r");
278
 
279
	if(read(w->ctl, &m, 1)  != 1)
280
		error("control file read error: %r");
281
 
282
	if (m == '0')
283
		return 0;
284
	else if (m == '1')
285
		return 1;
286
	else
287
		error("can't parse ismodified field: %c", m);
288
	return 1; // better safe than sorry
289
 
290
}
291
 
292
int
293
winsetaddr(Window *w, char *addr, int errok)
294
{
295
	if(w->addr < 0)
296
		w->addr = winopenfile(w, "addr");
297
	if(write(w->addr, addr, strlen(addr)) < 0){
298
		if(!errok)
299
			error("error writing addr(%s): %r", addr);
300
		return 0;
301
	}
302
	return 1;
303
}
304
 
305
int
306
winselect(Window *w, char *addr, int errok)
307
{
308
	if(winsetaddr(w, addr, errok)){
309
		ctlprint(w->ctl, "dot=addr\n");
310
		return 1;
311
	}
312
	return 0;
313
}
314
 
315
char*
316
winreadbody(Window *w, int *np)	/* can't use readfile because acme doesn't report the length */
317
{
318
	char *s;
319
	int m, na, n;
320
 
321
	if(w->body != nil)
322
		winclosebody(w);
323
	winopenbody(w, OREAD);
324
	s = nil;
325
	na = 0;
326
	n = 0;
327
	for(;;){
328
		if(na < n+512){
329
			na += 1024;
330
			s = realloc(s, na+1);
331
		}
332
		m = Bread(w->body, s+n, na-n);
333
		if(m <= 0)
334
			break;
335
		n += m;
336
	}
337
	s[n] = 0;
338
	winclosebody(w);
339
	*np = n;
340
	return s;
341
}