Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
n10.c
3
 
4
Device interfaces
5
*/
6
 
7
#include "tdef.h"
8
#include "ext.h"
9
#include "fns.h"
10
#include <ctype.h>
11
 
12
Term	t;	/* terminal characteristics */
13
 
14
int	dtab;
15
int	plotmode;
16
int	esct;
17
 
18
enum	{ Notype = 0, Type = 1 };
19
 
20
static char *parse(char *s, int typeit)	/* convert \0, etc to nroff driving table format */
21
{		/* typeit => add a type id to the front for later use */
22
	static char buf[100], *t, *obuf;
23
	int quote = 0;
24
	wchar_t wc;
25
 
26
	obuf = typeit == Type ? buf : buf+1;
27
#ifdef UNICODE
28
	if (mbtowc(&wc, s, strlen(s)) > 1) {	/* it's multibyte, */
29
		buf[0] = MBchar;
30
		strcpy(buf+1, s);
31
		return obuf;
32
	}			/* so just hand it back */
33
#endif	/*UNICODE*/
34
	buf[0] = Troffchar;
35
	t = buf + 1;
36
	if (*s == '"') {
37
		s++;
38
		quote = 1;
39
	}
40
	for (;;) {
41
		if (quote && *s == '"') {
42
			s++;			/* pointless */
43
			break;
44
		}
45
		if (!quote && (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\0'))
46
			break;
47
		if (*s != '\\')
48
			*t++ = *s++;
49
		else {
50
			s++;	/* skip \\ */
51
			if (isdigit(s[0]) && isdigit(s[1]) && isdigit(s[2])) {
52
				*t++ = (s[0]-'0')<<6 | (s[1]-'0')<<3 | s[2]-'0';
53
				s += 2;
54
			} else if (isdigit(s[0])) {
55
				*t++ = *s - '0';
56
			} else if (*s == 'b') {
57
				*t++ = '\b';
58
			} else if (*s == 'n') {
59
				*t++ = '\n';
60
			} else if (*s == 'r') {
61
				*t++ = '\r';
62
			} else if (*s == 't') {
63
				*t++ = '\t';
64
			} else {
65
				*t++ = *s;
66
			}
67
			s++;
68
		}
69
	}
70
	*t = '\0';
71
	return obuf;
72
}
73
 
74
 
75
static int getnrfont(FILE *fp)	/* read the nroff description file */
76
{
77
	Chwid chtemp[NCHARS];
78
	static Chwid chinit;
79
	int i, nw, n, wid, code, type;
80
	char buf[100], ch[100], s1[100], s2[100];
81
	wchar_t wc;
82
 
83
	code = 0;			/* no idea what this should be */
84
	chinit.wid = 1;
85
	chinit.str = "";
86
	for (i = 0; i < ALPHABET; i++) {
87
		chtemp[i] = chinit;	/* zero out to begin with */
88
		chtemp[i].num = chtemp[i].code = i;	/* every alphabetic character is itself */
89
		chtemp[i].wid = 1;	/* default ascii widths */
90
	}
91
	skipline(fp);
92
	nw = ALPHABET;
93
	while (fgets(buf, sizeof buf, fp) != NULL) {
94
		sscanf(buf, "%s %s %[^\n]", ch, s1, s2);
95
		if (!eq(s1, "\"")) {	/* genuine new character */
96
			sscanf(s1, "%d", &wid);
97
		} /* else it's a synonym for prev character, */
98
			/* so leave previous values intact */
99
 
100
		/* decide what kind of alphabet it might come from */
101
 
102
		if (strlen(ch) == 1) {	/* it's ascii */
103
			n = ch[0];	/* origin includes non-graphics */
104
			chtemp[n].num = ch[0];
105
		} else if (ch[0] == '\\' && ch[1] == '0') {
106
			n = strtol(ch+1, 0, 0);	/* \0octal or \0xhex */
107
			chtemp[n].num = n;
108
#ifdef UNICODE
109
		} else if (mbtowc(&wc, ch, strlen(ch)) > 1) {
110
			chtemp[nw].num = chadd(ch, MBchar, Install);
111
			n = nw;
112
			nw++;
113
#endif	/*UNICODE*/
114
		} else {
115
			if (strcmp(ch, "---") == 0) { /* no name */
116
				/* code used to be uninitialised here */
117
				sprintf(ch, "%d", code);
118
				type = Number;
119
			} else
120
				type = Troffchar;
121
/* BUG in here somewhere when same character occurs twice in table */
122
			chtemp[nw].num = chadd(ch, type, Install);
123
			n = nw;
124
			nw++;
125
		}
126
		chtemp[n].wid = wid;
127
		chtemp[n].str = strdupl(parse(s2, Type));
128
	}
129
	t.tfont.nchars = nw;
130
	t.tfont.wp = (Chwid *) malloc(nw * sizeof(Chwid));
131
	if (t.tfont.wp == NULL)
132
		return -1;
133
	for (i = 0; i < nw; i++)
134
		t.tfont.wp[i] = chtemp[i];
135
	return 1;
136
}
137
 
138
 
139
void n_ptinit(void)
140
{
141
	int i;
142
	char *p;
143
	char opt[50], cmd[100];
144
	FILE *fp;
145
 
146
	hmot = n_hmot;
147
	makem = n_makem;
148
	setabs = n_setabs;
149
	setch = n_setch;
150
	sethl = n_sethl;
151
	setht = n_setht;
152
	setslant = n_setslant;
153
	vmot = n_vmot;
154
	xlss = n_xlss;
155
	findft = n_findft;
156
	width = n_width;
157
	mchbits = n_mchbits;
158
	ptlead = n_ptlead;
159
	ptout = n_ptout;
160
	ptpause = n_ptpause;
161
	setfont = n_setfont;
162
	setps = n_setps;
163
	setwd = n_setwd;
164
 
165
	if ((p = getenv("NROFFTERM")) != 0)
166
		strcpy(devname, p);
167
	if (termtab[0] == 0)
168
		strcpy(termtab,DWBntermdir);
169
	if (fontdir[0] == 0)
170
		strcpy(fontdir, "");
171
	if (devname[0] == 0)
172
		strcpy(devname, NDEVNAME);
173
	pl = 11*INCH;
174
	po = PO;
175
	hyf = 0;
176
	ascii = 1;
177
	lg = 0;
178
	fontlab[1] = 'R';
179
	fontlab[2] = 'I';
180
	fontlab[3] = 'B';
181
	fontlab[4] = PAIR('B','I');
182
	fontlab[5] = 'D';
183
	bdtab[3] = 3;
184
	bdtab[4] = 3;
185
 
186
	/* hyphalg = 0;	/* for testing */
187
 
188
	strcat(termtab, devname);
189
	if ((fp = fopen(termtab, "r")) == NULL) {
190
		ERROR "cannot open %s", termtab WARN;
191
		exit(-1);
192
	}
193
 
194
 
195
/* this loop isn't robust about input format errors. */
196
/* it assumes  name, name-value pairs..., charset */
197
/* god help us if we get out of sync. */
198
 
199
	fscanf(fp, "%s", cmd);	/* should be device name... */
200
	if (!is(devname) && trace)
201
		ERROR "wrong terminal name: saw %s, wanted %s", cmd, devname WARN;
202
	for (;;) {
203
		fscanf(fp, "%s", cmd);
204
		if (is("charset"))
205
			break;
206
		fscanf(fp, " %[^\n]", opt);
207
		if (is("bset")) t.bset = atoi(opt);
208
		else if (is("breset")) t.breset = atoi(opt);
209
		else if (is("Hor")) t.Hor = atoi(opt);
210
		else if (is("Vert")) t.Vert = atoi(opt);
211
		else if (is("Newline")) t.Newline = atoi(opt);
212
		else if (is("Char")) t.Char = atoi(opt);
213
		else if (is("Em")) t.Em = atoi(opt);
214
		else if (is("Halfline")) t.Halfline = atoi(opt);
215
		else if (is("Adj")) t.Adj = atoi(opt);
216
		else if (is("twinit")) t.twinit = strdupl(parse(opt, Notype));
217
		else if (is("twrest")) t.twrest = strdupl(parse(opt, Notype));
218
		else if (is("twnl")) t.twnl = strdupl(parse(opt, Notype));
219
		else if (is("hlr")) t.hlr = strdupl(parse(opt, Notype));
220
		else if (is("hlf")) t.hlf = strdupl(parse(opt, Notype));
221
		else if (is("flr")) t.flr = strdupl(parse(opt, Notype));
222
		else if (is("bdon")) t.bdon = strdupl(parse(opt, Notype));
223
		else if (is("bdoff")) t.bdoff = strdupl(parse(opt, Notype));
224
		else if (is("iton")) t.iton = strdupl(parse(opt, Notype));
225
		else if (is("itoff")) t.itoff = strdupl(parse(opt, Notype));
226
		else if (is("ploton")) t.ploton = strdupl(parse(opt, Notype));
227
		else if (is("plotoff")) t.plotoff = strdupl(parse(opt, Notype));
228
		else if (is("up")) t.up = strdupl(parse(opt, Notype));
229
		else if (is("down")) t.down = strdupl(parse(opt, Notype));
230
		else if (is("right")) t.right = strdupl(parse(opt, Notype));
231
		else if (is("left")) t.left = strdupl(parse(opt, Notype));
232
		else
233
			ERROR "bad tab.%s file, %s %s", devname, cmd, opt WARN;
234
	}
235
 
236
	getnrfont(fp);
237
	fclose(fp);
238
 
239
	sps = EM;
240
	ics = EM * 2;
241
	dtab = 8 * t.Em;
242
	for (i = 0; i < 16; i++)
243
		tabtab[i] = dtab * (i + 1);
244
	pl = 11 * INCH;
245
	po = PO;
246
	spacesz = SS;
247
	lss = lss1 = VS;
248
	ll = ll1 = lt = lt1 = LL;
249
	smnt = nfonts = 5;	/* R I B BI S */
250
	n_specnames();	/* install names like "hyphen", etc. */
251
	if (eqflg)
252
		t.Adj = t.Hor;
253
}
254
 
255
 
256
void n_specnames(void)
257
{
258
 
259
	int	i;
260
 
261
	for (i = 0; spnames[i].n; i++)
262
		*spnames[i].n = chadd(spnames[i].v, Troffchar, Install);
263
	if (c_isalnum == 0)
264
		c_isalnum = NROFFCHARS;
265
}
266
 
267
void twdone(void)
268
{
269
	if (!TROFF && t.twrest) {
270
		obufp = obuf;
271
		oputs(t.twrest);
272
		flusho();
273
		if (pipeflg) {
274
			pclose(ptid);
275
		}
276
		restore_tty();
277
	}
278
}
279
 
280
 
281
void n_ptout(Tchar i)
282
{
283
	*olinep++ = i;
284
	if (olinep >= &oline[LNSIZE])
285
		olinep--;
286
	if (cbits(i) != '\n')
287
		return;
288
	olinep--;
289
	lead += dip->blss + lss - t.Newline;
290
	dip->blss = 0;
291
	esct = esc = 0;
292
	if (olinep > oline) {
293
		move();
294
		ptout1();
295
		oputs(t.twnl);
296
	} else {
297
		lead += t.Newline;
298
		move();
299
	}
300
	lead += dip->alss;
301
	dip->alss = 0;
302
	olinep = oline;
303
}
304
 
305
 
306
void ptout1(void)
307
{
308
	int k;
309
	char *codep;
310
	int w, j, phyw;
311
	Tchar *q, i;
312
	static int oxfont = FT;	/* start off in roman */
313
 
314
	for (q = oline; q < olinep; q++) {
315
		i = *q;
316
		if (ismot(i)) {
317
			j = absmot(i);
318
			if (isnmot(i))
319
				j = -j;
320
			if (isvmot(i))
321
				lead += j;
322
			else 
323
				esc += j;
324
			continue;
325
		}
326
		if ((k = cbits(i)) <= ' ') {
327
			switch (k) {
328
			case ' ': /*space*/
329
				esc += t.Char;
330
				break;
331
			case '\033':
332
			case '\007':
333
			case '\016':
334
			case '\017':
335
				oput(k);
336
				break;
337
			}
338
			continue;
339
		}
340
		phyw = w = t.Char * t.tfont.wp[k].wid;
341
		if (iszbit(i))
342
			w = 0;
343
		if (esc || lead)
344
			move();
345
		esct += w;
346
		xfont = fbits(i);
347
		if (xfont != oxfont) {
348
			switch (oxfont) {
349
			case ULFONT:	oputs(t.itoff); break;
350
			case BDFONT:	oputs(t.bdoff); break;
351
			case BIFONT:	oputs(t.itoff); oputs(t.bdoff); break;
352
			}
353
			switch (xfont) {
354
			case ULFONT:
355
				if (*t.iton & 0377) oputs(t.iton); break;
356
			case BDFONT:
357
				if (*t.bdon & 0377) oputs(t.bdon); break;
358
			case BIFONT:
359
				if (*t.bdon & 0377) oputs(t.bdon);
360
				if (*t.iton & 0377) oputs(t.iton);
361
				break;
362
			}
363
			oxfont = xfont;
364
		}
365
		if ((xfont == ulfont || xfont == BIFONT) && !(*t.iton & 0377)) {
366
			for (j = w / t.Char; j > 0; j--)
367
				oput('_');
368
			for (j = w / t.Char; j > 0; j--)
369
				oput('\b');
370
		}
371
		if (!(*t.bdon & 0377) && ((j = bdtab[xfont]) || xfont == BDFONT || xfont == BIFONT))
372
			j++;
373
		else
374
			j = 1;	/* number of overstrikes for bold */
375
		if (k < ALPHABET) {	/* ordinary ascii */
376
			oput(k);
377
			while (--j > 0) {
378
				oput('\b');
379
				oput(k);
380
			}
381
		} else if (k >= t.tfont.nchars) {	/* BUG -- not really understood */
382
/* fprintf(stderr, "big char %d, name %s\n", k, chname(k)); /* */
383
			oputs(chname(k)+1);	/* BUG: should separate Troffchar and MBchar... */
384
		} else if (t.tfont.wp[k].str == 0) {
385
/* fprintf(stderr, "nostr char %d, name %s\n", k, chname(k)); /* */
386
			oputs(chname(k)+1);	/* BUG: should separate Troffchar and MBchar... */
387
		} else if (t.tfont.wp[k].str[0] == MBchar) {	/* parse() puts this on */
388
/* fprintf(stderr, "MBstr char %d, name %s\n", k, chname(k)); /* */
389
			oputs(t.tfont.wp[k].str+1);
390
		} else {
391
			int oj = j;
392
/* fprintf(stderr, "str char %d, name %s\n", k, chname(k)); /* */
393
			codep = t.tfont.wp[k].str+1;	/* Troffchar by default */
394
			while (*codep != 0) {
395
				if (*codep & 0200) {
396
					codep = plot(codep);
397
					oput(' ');
398
				} else {
399
					if (*codep == '%')	/* escape */
400
						codep++;
401
					oput(*codep);
402
					if (*codep == '\033')
403
						oput(*++codep);
404
					else if (*codep != '\b')
405
						for (j = oj; --j > 0; ) {
406
							oput('\b');
407
							oput(*codep);
408
						}
409
					codep++;
410
				}
411
			}
412
		}
413
		if (!w)
414
			for (j = phyw / t.Char; j > 0; j--)
415
				oput('\b');
416
	}
417
}
418
 
419
 
420
char *plot(char *x)
421
{
422
	int	i;
423
	char	*j, *k;
424
 
425
	oputs(t.ploton);
426
	k = x;
427
	if ((*k & 0377) == 0200)
428
		k++;
429
	for (; *k; k++) {
430
		if (*k == '%') {	/* quote char within plot mode */
431
			oput(*++k);
432
		} else if (*k & 0200) {
433
			if (*k & 0100) {
434
				if (*k & 040)
435
					j = t.up; 
436
				else 
437
					j = t.down;
438
			} else {
439
				if (*k & 040)
440
					j = t.left; 
441
				else 
442
					j = t.right;
443
			}
444
			if ((i = *k & 037) == 0) {	/* 2nd 0200 turns it off */
445
				++k;
446
				break;
447
			}
448
			while (i--)
449
				oputs(j);
450
		} else 
451
			oput(*k);
452
	}
453
	oputs(t.plotoff);
454
	return(k);
455
}
456
 
457
 
458
void move(void)
459
{
460
	int k;
461
	char *i, *j;
462
	char *p, *q;
463
	int iesct, dt;
464
 
465
	iesct = esct;
466
	if (esct += esc)
467
		i = "\0"; 
468
	else 
469
		i = "\n\0";
470
	j = t.hlf;
471
	p = t.right;
472
	q = t.down;
473
	if (lead) {
474
		if (lead < 0) {
475
			lead = -lead;
476
			i = t.flr;
477
			/*	if(!esct)i = t.flr; else i = "\0";*/
478
			j = t.hlr;
479
			q = t.up;
480
		}
481
		if (*i & 0377) {
482
			k = lead / t.Newline;
483
			lead = lead % t.Newline;
484
			while (k--)
485
				oputs(i);
486
		}
487
		if (*j & 0377) {
488
			k = lead / t.Halfline;
489
			lead = lead % t.Halfline;
490
			while (k--)
491
				oputs(j);
492
		} else { /* no half-line forward, not at line begining */
493
			k = lead / t.Newline;
494
			lead = lead % t.Newline;
495
			if (k > 0) 
496
				esc = esct;
497
			i = "\n";
498
			while (k--) 
499
				oputs(i);
500
		}
501
	}
502
	if (esc) {
503
		if (esc < 0) {
504
			esc = -esc;
505
			j = "\b";
506
			p = t.left;
507
		} else {
508
			j = " ";
509
			if (hflg)
510
				while ((dt = dtab - (iesct % dtab)) <= esc) {
511
					if (dt % t.Em)
512
						break;
513
					oput(TAB);
514
					esc -= dt;
515
					iesct += dt;
516
				}
517
		}
518
		k = esc / t.Em;
519
		esc = esc % t.Em;
520
		while (k--)
521
			oputs(j);
522
	}
523
	if ((*t.ploton & 0377) && (esc || lead)) {
524
		oputs(t.ploton);
525
		esc /= t.Hor;
526
		lead /= t.Vert;
527
		while (esc--)
528
			oputs(p);
529
		while (lead--)
530
			oputs(q);
531
		oputs(t.plotoff);
532
	}
533
	esc = lead = 0;
534
}
535
 
536
 
537
void n_ptlead(void)
538
{
539
	move();
540
}
541
 
542
 
543
void n_ptpause(void )
544
{
545
	char	junk;
546
 
547
	flusho();
548
	read(2, &junk, 1);
549
}