Introduction
Introduction Statistics Contact Development Disclaimer Help
n10.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
n10.c (11599B)
---
1 /*
2 n10.c
3
4 Device interfaces
5 */
6
7 #include <u.h>
8 #include "tdef.h"
9 #include "ext.h"
10 #include "fns.h"
11 #include <ctype.h>
12
13 Term t; /* terminal characteristics */
14
15 int dtab;
16 int plotmode;
17 int esct;
18
19 enum { Notype = 0, Type = 1 };
20
21 static char *parse(char *s, int typeit) /* convert \0, etc to nro…
22 { /* typeit => add a type id to the front for later use */
23 static char buf[100], *t, *obuf;
24 int quote = 0;
25 wchar_t wc;
26
27 obuf = typeit == Type ? buf : buf+1;
28 #ifdef UNICODE
29 if (mbtowc(&wc, s, strlen(s)) > 1) { /* it's multibyte, */
30 buf[0] = MBchar;
31 strcpy(buf+1, s);
32 return obuf;
33 } /* so just hand it back */
34 #endif /*UNICODE*/
35 buf[0] = Troffchar;
36 t = buf + 1;
37 if (*s == '"') {
38 s++;
39 quote = 1;
40 }
41 for (;;) {
42 if (quote && *s == '"') {
43 s++;
44 break;
45 }
46 if (!quote && (*s == ' ' || *s == '\t' || *s == '\n' || …
47 break;
48 if (*s != '\\')
49 *t++ = *s++;
50 else {
51 s++; /* skip \\ */
52 if (isdigit((uchar)s[0]) && isdigit((uchar)s[1])…
53 *t++ = (s[0]-'0')<<6 | (s[1]-'0')<<3 | s…
54 s += 2;
55 } else if (isdigit((uchar)s[0])) {
56 *t++ = *s - '0';
57 } else if (*s == 'b') {
58 *t++ = '\b';
59 } else if (*s == 'n') {
60 *t++ = '\n';
61 } else if (*s == 'r') {
62 *t++ = '\r';
63 } else if (*s == 't') {
64 *t++ = '\t';
65 } else {
66 *t++ = *s;
67 }
68 s++;
69 }
70 }
71 *t = '\0';
72 return obuf;
73 }
74
75
76 static int getnrfont(FILE *fp) /* read the nroff description file…
77 {
78 Chwid chtemp[NCHARS];
79 static Chwid chinit;
80 int i, nw, n, wid, code, type;
81 char buf[100], ch[100], s1[100], s2[100];
82 wchar_t wc;
83
84 code = 0;
85 chinit.wid = 1;
86 chinit.str = "";
87 for (i = 0; i < ALPHABET; i++) {
88 chtemp[i] = chinit; /* zero out to begin with */
89 chtemp[i].num = chtemp[i].code = i; /* every alph…
90 chtemp[i].wid = 1; /* default ascii widths */
91 }
92 skipline(fp);
93 nw = ALPHABET;
94 while (fgets(buf, sizeof buf, fp) != NULL) {
95 sscanf(buf, "%s %s %[^\n]", ch, s1, s2);
96 if (!eq(s1, "\"")) { /* genuine new character */
97 sscanf(s1, "%d", &wid);
98 } /* else it's a synonym for prev character, */
99 /* so leave previous values intact */
100
101 /* decide what kind of alphabet it might come from */
102
103 if (strlen(ch) == 1) { /* it's ascii */
104 n = ch[0]; /* origin includes non-graphic…
105 chtemp[n].num = ch[0];
106 } else if (ch[0] == '\\' && ch[1] == '0') {
107 n = strtol(ch+1, 0, 0); /* \0octal or \0x…
108 chtemp[n].num = n;
109 #ifdef UNICODE
110 } else if (mbtowc(&wc, ch, strlen(ch)) > 1) {
111 chtemp[nw].num = chadd(ch, MBchar, Install);
112 n = nw;
113 nw++;
114 #endif /*UNICODE*/
115 } else {
116 if (strcmp(ch, "---") == 0) { /* no name */
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(unsharp(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, dev…
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, Not…
217 else if (is("twrest")) t.twrest = strdupl(parse(opt, Not…
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, Notyp…
224 else if (is("iton")) t.iton = strdupl(parse(opt, Notype)…
225 else if (is("itoff")) t.itoff = strdupl(parse(opt, Notyp…
226 else if (is("ploton")) t.ploton = strdupl(parse(opt, Not…
227 else if (is("plotoff")) t.plotoff = strdupl(parse(opt, N…
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, Notyp…
231 else if (is("left")) t.left = strdupl(parse(opt, Notype)…
232 else
233 ERROR "bad tab.%s file, %s %s", devname, cmd, op…
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.bdof…
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 & …
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 ==…
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 r…
382 /* fprintf(stderr, "big char %d, name %s\n", k, chname(k)); /* */
383 oputs(chname(k)+1); /* BUG: should separa…
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 separa…
387 } else if (t.tfont.wp[k].str[0] == MBchar) { /* p…
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…
394 while (*codep != 0) {
395 if (*codep & 0200) {
396 codep = plot(codep);
397 oput(' ');
398 } else {
399 if (*codep == '%') /* esc…
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 tu…
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)) <= e…
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 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.