|
|
1.1 root 1: #include <X/mit-copyright.h>
2:
3: /* Copyright (c) 1985 Massachusetts Institute of Technology */
4: /* Copyright (c) 1985 Digital Equipment Corporation */
5:
6: /* charproc.c */
7:
8: #include <X/Xlib.h>
9: #include "ptyx.h"
10: #include <stdio.h>
11: #include <sgtty.h>
12: #include "chartable.h"
13: #include "esctable.h"
14:
15: #ifndef lint
16: static char *rcsid_charproc_c = "$Header: charproc.c,v 10.10 86/02/01 16:05:52 tony Rel $";
17: #endif lint
18:
19: /* CAUTION: getb "knows" that the variable "c" is receiving the result */
20:
21: #define getb(buf) (--buf_cnt >= 0 ? *buf_ptr++: \
22: ((c=fill(buf)), buf_cnt=buf->cnt, buf_ptr=buf->ptr, c))
23:
24: #define peekb(buf) (buf_cnt > 0 ? *buf_ptr : -1)
25:
26: #define ANSIflush() { arg = flushbuf(screen, term->flags, text_ptr); \
27: buffermode = 0; \
28: text_ptr = text_buf; \
29: text_cnt = TEXT_BUF_SIZE; }
30:
31: #define TEKflush() { arg = TekFlushBuf(term, text_ptr); \
32: buffermode = 0; \
33: text_ptr = text_buf; \
34: text_cnt = TEXT_BUF_SIZE; \
35: }
36:
37: #define TEXT_BUF_SIZE 256
38:
39: extern TekLink *tb_end_link;
40: extern int tb_end;
41:
42: unsigned char text_buf[TEXT_BUF_SIZE];
43:
44: unsigned nri = 0;
45: unsigned nlf = 0;
46: unsigned ctotal = 0;
47: unsigned ntotal = 0;
48:
49: /*
50: * in normal mode, buffer up as large a string of printing characters
51: * as possible before flushing the buffer. buffer up LF's and RI's
52: * so these can be processed as a block.
53: */
54: ANSInormal(term)
55: Terminal *term;
56: {
57: register int c;
58: register unsigned char *text_ptr;
59: register int text_cnt;
60: register unsigned char *buf_ptr;
61: register int buf_cnt;
62: register unsigned buffermode;
63: register Screen *screen = &term->screen;
64: register Buffer *trmbuf = &term->buf;
65: int arg;
66:
67: buffermode = 0;
68: arg = 0;
69: c = 0;
70: text_ptr = text_buf;
71: text_cnt = TEXT_BUF_SIZE;
72: buf_cnt = trmbuf->cnt;
73: buf_ptr = trmbuf->ptr;
74:
75: if (screen->TekGMode || screen->TekAMode)
76: return (TekMode(term));
77:
78: for (;;) {
79: /*
80: * if special condition has occurred, c will already
81: * be set to EOF. otherwise, pick up a new char.
82: */
83: if (c >= 0)
84: c = getb(trmbuf);
85:
86: if (ctable[c] == CPRINTING) {
87: buffermode = BUFFER_MODE;
88: if (--text_cnt >= 0)
89: *text_ptr++ = c;
90: else {
91: ANSIflush();
92: --text_cnt, *text_ptr++ = c;
93: if (arg)
94: c = EOF;
95: }
96: continue;
97:
98: }
99:
100: switch (ctable[c]) {
101: case CIGNORE:
102: break;
103:
104:
105: case CLINEFEED:
106: if (buffermode || nri) {
107: ANSIflush();
108: if (arg)
109: c = EOF;
110: }
111: ++nlf;
112: break;
113:
114: case CRETURN:
115: if (buffermode) {
116: ANSIflush();
117: if (arg)
118: c = EOF;
119: }
120: screen->cur_col = 0;
121: screen->do_wrap = 0;
122: break;
123:
124: case CRI:
125: RI_kluge: if (buffermode || nlf) {
126: ANSIflush();
127: if (arg)
128: c = EOF;
129: }
130: ++nri;
131: break;
132:
133: case FLUSH:
134: ANSIflush();
135: trmbuf->cnt = buf_cnt;
136: trmbuf->ptr = buf_ptr;
137: return (arg);
138:
139: case CESC:
140: /* try to intercept RI's so we can buffer them */
141: if (peekb(trmbuf) == 'M') {
142: c = getb(trmbuf);
143: goto RI_kluge;
144: }
145: /* no RI detected; fall into default case */
146:
147: default:
148: ANSIflush();
149: docontrol(term, c);
150:
151: /*
152: * if mode changes or event occurs, force a
153: * cleanup and return by setting char to EOF
154: */
155: if (arg
156: || screen->mode!=ANSInormal
157: || screen->TekGMode
158: || screen->TekAMode)
159: c = EOF;
160: }
161: }
162: }
163:
164: /*
165: * flush the buffer of printing characters. first, process any LF's or
166: * RI's that have been buffered.
167: */
168: flushbuf(screen, flags, text_ptr)
169: register Screen *screen;
170: unsigned flags;
171: register unsigned char *text_ptr;
172: {
173: register unsigned char *s;
174: register unsigned char *p;
175: int arg = 0;
176:
177: if (nri != 0) {
178: ioctl(screen->display->fd, FIONREAD, &arg);
179: RevIndex(screen, nri);
180: nri = 0;
181: }
182: if (nlf != 0) {
183: ioctl(screen->display->fd, FIONREAD, &arg);
184: Index(screen, nlf);
185: if (flags & LINEFEED) { /* do a carriage return */
186: screen->cur_col = 0;
187: screen->do_wrap = 0;
188: }
189: nlf = 0;
190: }
191:
192: s = text_buf;
193: /*
194: * if a single shift is in effect, process
195: * the one character it affects.
196: */
197: if (screen->curss!=0 && s<text_ptr) {
198: dotext(screen, flags, screen->gsets[screen->curss], s, s+1);
199: ++s;
200: screen->curss = 0;
201: }
202:
203: /*
204: * characters with and without the high bit set must be processed
205: * separately (they select different character sets). collect them
206: * into groups before processing for as much efficiency as possible.
207: */
208: while (s < text_ptr) {
209: p = s;
210: if (*s < 0x80) {
211: /* character doesn't have high bit set */
212: while (*s<0x80 && s<text_ptr)
213: ++s;
214: dotext(screen, flags,
215: screen->gsets[screen->curgl], p, s);
216: }
217: else { /* character has high bit set */
218: while (*s>=0x80 && s<text_ptr) {
219: *s &= 0x7f;
220: ++s;
221: }
222: dotext(screen, flags,
223: screen->gsets[screen->curgr], p, s);
224: }
225: }
226:
227: return (arg || screen->display->qlen!=0);
228: }
229:
230: /*
231: * process a string of characters according to the character set indicated
232: * by charset. worry about end of line conditions (wraparound if selected).
233: */
234: dotext(screen, flags, charset, buf, ptr)
235: register Screen *screen;
236: unsigned flags;
237: char charset;
238: unsigned char *buf;
239: unsigned char *ptr;
240: {
241: register unsigned char *s;
242: register int len;
243: register int n;
244: register int next_col;
245:
246: switch (charset) {
247: case 'A': /* United Kingdom set */
248: for (s=buf; s<ptr; ++s)
249: if (*s == '#')
250: *s = '\036'; /* UK pound sign */
251: break;
252:
253: case 'B': /* ASCII set */
254: break;
255:
256: case '0': /* special graphics (line drawing) */
257: for (s=buf; s<ptr; ++s)
258: if (*s>=0x5f && *s<=0x7e)
259: *s = *s - 0x5f;
260: break;
261:
262: default: /* any character sets we don't recognize */
263: return;
264: }
265:
266: len = ptr - buf;
267: ptr = buf;
268: while (len > 0) {
269: n = screen->max_col-screen->cur_col+1;
270: if (n <= 1) {
271: if (screen->do_wrap && (flags&WRAPAROUND)) {
272: Index(screen, 1);
273: screen->cur_col = 0;
274: screen->do_wrap = 0;
275: n = screen->max_col+1;
276: }
277: else
278: n = 1;
279: }
280: if (len < n)
281: n = len;
282: next_col = screen->cur_col + n;
283: WriteText(screen, ptr, n, flags);
284: /*
285: * the call to WriteText updates screen->cur_col.
286: * If screen->cur_col != next_col, we must have
287: * hit the right margin, so set the do_wrap flag.
288: */
289: screen->do_wrap = (screen->cur_col < next_col);
290: len -= n;
291: ptr += n;
292: }
293: }
294:
295: /*
296: * write a string str of length len onto the screen at
297: * the current cursor position. update cursor position.
298: */
299: WriteText(screen, str, len, flags)
300: register Screen *screen;
301: register unsigned char *str;
302: register int len;
303: unsigned flags;
304: {
305: Font fnt;
306:
307: fnt = (flags & BOLD ? screen->fnt_bold : screen->fnt_norm);
308: if (flags & INSERT)
309: InsertChar(screen, len);
310: #ifdef JUMPSCROLL
311: if (!(AddToRefresh(screen))) {
312: if(screen->scroll_amt)
313: FlushScroll(screen);
314: #endif JUMPSCROLL
315: if (flags & INVERSE)
316: XText(screen->window, CursorX(screen), CursorY(screen),
317: str, len, fnt, screen->background, screen->foreground);
318: else
319: XText(screen->window, CursorX(screen), CursorY(screen),
320: str, len, fnt, screen->foreground, screen->background);
321: /*
322: * the following statements compile data to compute the average
323: * number of characters written on each call to XText. The data
324: * may be examined via the use of a "hidden" escape sequence.
325: */
326: ctotal += len;
327: ++ntotal;
328: #ifdef JUMPSCROLL
329: }
330: #endif JUMPSCROLL
331: ScreenWrite(screen, str, flags, len);
332: CursorForward(screen, len);
333: }
334:
335: /*
336: * in Tek mode (graphics or alpha), buffer up as large a string of printing
337: * characters as possible before flushing buffer. in graphics mode the
338: * characters are plotted, in alpha mode they are printed.
339: */
340: TekMode(term)
341: Terminal *term;
342: {
343: register int c;
344: register unsigned char *text_ptr;
345: register int text_cnt;
346: register unsigned char *buf_ptr;
347: register int buf_cnt;
348: register unsigned buffermode;
349: register Screen *screen = &term->screen;
350: register Buffer *trmbuf = &term->buf;
351: int arg;
352:
353: c = 0;
354: buffermode = 0;
355: text_ptr = text_buf;
356: text_cnt = TEXT_BUF_SIZE;
357: buf_cnt = trmbuf->cnt;
358: buf_ptr = trmbuf->ptr;
359:
360: for (;;) {
361: /*
362: * if special condition has occurred, c will already
363: * be set to EOF. otherwise, pick up a new char.
364: */
365: if (c >= 0)
366: c = getb(trmbuf);
367:
368: if (c > 0)
369: c &= 0x7f;
370:
371: if (ctable[c]==CPRINTING || (c==DEL && screen->TekGMode)) {
372: buffermode = BUFFER_MODE;
373: if (--text_cnt >= 0)
374: *text_ptr++ = c;
375: else {
376: TEKflush();
377: --text_cnt, *text_ptr++ = c;
378: if (arg)
379: c = EOF;
380: }
381: continue;
382:
383: }
384:
385: switch (ctable[c]) {
386: case CIGNORE:
387: break;
388:
389: case CTEKINIT:
390: if (buffermode)
391: TEKflush();
392: TekInit(term, c);
393: if (arg)
394: c = EOF;
395: break;
396:
397: case FLUSH:
398: TEKflush();
399: trmbuf->cnt = buf_cnt;
400: trmbuf->ptr = buf_ptr;
401: return (arg);
402:
403: default: /* BEL, BS, HT, LF, VT, FF, CR, ESC, US */
404: /* and also SI, SO, CAN, SUB */
405: TEKflush();
406: if (screen->TekGMode)
407: TekAlph(term, c);
408: docontrol(term, c);
409:
410: /*
411: * if mode changes or event occurs, force a
412: * cleanup and return by setting char to EOF
413: */
414: if (arg || screen->mode!=ANSInormal
415: || (screen->TekGMode==0 && screen->TekAMode==0))
416: c = EOF;
417: }
418: }
419: }
420:
421: /*
422: * flush the buffer of printing characters.
423: * use TekString, TekPoint, or TekPlot according to current mode.
424: */
425: TekFlushBuf(term, text_ptr)
426: Terminal *term;
427: register unsigned char *text_ptr;
428: {
429: register Screen *screen = &term->screen;
430: register unsigned char *s;
431:
432: s = text_buf;
433: if (text_ptr != text_buf) {
434: if (screen->TekGMode) {
435: if (screen->TekIMode)
436: while (s < text_ptr) {
437: TekBufPut(*s);
438: TekPoint(term, *s++);
439: }
440: else
441: while (s < text_ptr) {
442: TekBufPut(*s);
443: TekPlot(term, *s++);
444: }
445: }
446: else
447: TekString(term, text_buf, text_ptr-text_buf);
448: }
449:
450: return (screen->display->qlen != 0);
451: }
452:
453: /*
454: * a string (DCS, OSC, PM, APC) has been encountered in ANSI mode.
455: * all printing characters are ignored until a string terminator
456: * is seen (other possible exits are CAN, SUB, ESC, and C1 controls).
457: */
458: ANSIstring(term)
459: Terminal *term;
460: {
461: register int c;
462: register Screen *screen = &term->screen;
463: register Buffer *trmbuf = &term->buf;
464: register unsigned char *buf_ptr;
465: register int buf_cnt;
466:
467: buf_cnt = trmbuf->cnt;
468: buf_ptr = trmbuf->ptr;
469: while (screen->mode==ANSIstring && screen->display->qlen==0) {
470: if ((c=getb(trmbuf)) == -1)
471: break;
472: if ((c=parseseq(c, &screen->ansi, screen->TekEmu)) != -1) {
473: switch (ctable[c]) {
474: case CIGNORE:
475: case CPRINTING:
476: break;
477: case CESC:
478: case CCSI:
479: screen->mode = ANSInormal;
480: procseq(term);
481: break;
482: case CDCS:
483: screen->mode = ANSIstring;
484: procseq(term);
485: break;
486: case CCANCEL:
487: screen->mode = ANSInormal;
488: break;
489: default:
490: break;
491: }
492: }
493: }
494: trmbuf->cnt = buf_cnt;
495: trmbuf->ptr = buf_ptr;
496: return (screen->display->qlen != 0);
497: }
498:
499: /*
500: * call parseseq with each new character until the sequence has been
501: * parsed. once parsed, call procseq to process the sequence. DEC
502: * standard says C0 controls in the middle of a sequence are acted
503: * on just as if they weren't in the middle of a sequence (ANSI says
504: * this is an error condition, but as always doesn't specify how to
505: * handle the error).
506: */
507: ANSIparse(term)
508: Terminal *term;
509: {
510: register int c, ch;
511: register Screen *screen = &term->screen;
512: register Buffer *trmbuf = &term->buf;
513: register unsigned char *buf_ptr;
514: register int buf_cnt;
515:
516: c = 0;
517: buf_cnt = trmbuf->cnt;
518: buf_ptr = trmbuf->ptr;
519:
520: for (;;) {
521: /*
522: * if special condition has occurred, c will already
523: * be set to EOF. otherwise, pick up a new char.
524: */
525: if (c >= 0)
526: c = getb(trmbuf);
527:
528: if (c == EOF) {
529: trmbuf->cnt = buf_cnt;
530: trmbuf->ptr = buf_ptr;
531: return (screen->display->qlen != 0);
532: }
533:
534: if ((ch=parseseq(c, &screen->ansi, screen->TekEmu)) != -1) {
535: switch (ctable[ch]) {
536: case CIGNORE:
537: break;
538:
539: case CESC:
540: case CCSI:
541: screen->mode = ANSInormal;
542: procseq(term);
543: break;
544:
545: case CDCS:
546: screen->mode = ANSIstring;
547: procseq(term);
548: break;
549:
550: default:
551: docontrol(term, ch);
552: break;
553: }
554:
555: /*
556: * if mode changes or event occurs, force a
557: * cleanup and return by setting char to EOF
558: */
559: if (screen->mode!=ANSIparse || screen->ansi.a_type==0) {
560: c = EOF;
561: if (screen->mode==ANSIparse)
562: screen->mode = ANSInormal;
563: screen->ansi.a_type = 0;
564: screen->ansi.a_pintro = 0;
565: screen->ansi.a_final = 0;
566: }
567: if (screen->display->qlen != 0);
568: c = EOF;
569:
570: }
571: }
572: }
573:
574: /*
575: * some sort of ANSI sequence has been parsed. look through the
576: * esctable to look for a match. if found, apply default parameters
577: * and dispatch.
578: */
579: procseq(term)
580: Terminal *term;
581: {
582: register ANSI *ap = &term->screen.ansi;
583: register int i;
584: register long *p;
585: register long a_funct;
586: #define SEQKEY p[0] /* type, private, & final in a long */
587: #define INTERS p[1] /* intermediate(s) in a long */
588: #define SEQTYPE p[2] /* sequence type (dispatch value) */
589: #define NDEFLT p[3] /* number of default parameters */
590: #define DEFAULT(n) p[4+n] /* the n'th default parameter (0 origin)*/
591: #define FIXEDLEN 4 /* fixed (min) length of table entries */
592:
593: /*
594: * just return if any error encountered
595: */
596: if (ap->a_nastyf != 0)
597: return;
598:
599: a_funct = (ap->a_final << 16) | (ap->a_pintro << 8) | ap->a_type;
600:
601: /*
602: * step through table, looking for an
603: * entry which matches the current sequence.
604: */
605: for (p=esctable; *p!=0; p+=NDEFLT+FIXEDLEN) {
606: if (SEQKEY==a_funct
607: && (INTERS==ap->a_inters || INTERS==WILD)) {
608: /*
609: * we have a match.
610: * get default values from table.
611: */
612: for (i=0; i<NDEFLT; ++i) {
613: if (ap->a_dflt[i] || i>=ap->a_nparam)
614: ap->a_param[i] = DEFAULT(i);
615: }
616: if (ap->a_nparam < NDEFLT)
617: ap->a_nparam = NDEFLT;
618: /*
619: * ready to process the sequence.
620: */
621: doescape(term, SEQTYPE, ap);
622: break;
623: }
624: }
625: }
626:
627: /*
628: * this is a big switch of all the ANSI (and other) sequences
629: * we know how to handle. the cases of the switch must
630: * have a corresponding entry in the esctable.
631: */
632: doescape(term, kind, ap)
633: Terminal *term;
634: long kind;
635: ANSI *ap;
636: {
637: register Screen *screen = &term->screen;
638: register row, col;
639: register i, top, bot;
640: ANSI reply;
641: int bitset(), bitclr();
642: register unsigned char *text_ptr;
643: register int text_cnt;
644:
645: switch (kind) {
646: case DECKPAM:
647: term->keyboard.flags |= KYPD_APL;
648: break;
649:
650: case DECKPNM:
651: term->keyboard.flags &= ~KYPD_APL;
652: break;
653:
654: case DECTC1:
655: screen->rx8bit = 0;
656: break;
657:
658: case DECSC:
659: screen->sc.row = screen->cur_row;
660: screen->sc.col = screen->cur_col;
661: screen->sc.flags = term->flags;
662: break;
663:
664: case DECAC1:
665: screen->rx8bit = 1;
666: break;
667:
668: case S7C1T:
669: screen->tx8bit = 0;
670: break;
671:
672: case S8C1T:
673: screen->tx8bit = 1;
674: break;
675:
676: case DECRC:
677: term->flags &= ~(BOLD|INVERSE);
678: term->flags |= screen->sc.flags&(BOLD|INVERSE);
679: CursorSet(screen, screen->sc.row,
680: screen->sc.col, term->flags);
681: break;
682:
683: case LS2:
684: screen->curgl = 2;
685: break;
686:
687: case LS3:
688: screen->curgl = 3;
689: break;
690:
691: case LS3R:
692: screen->curgr = 3;
693: break;
694:
695: case LS2R:
696: screen->curgr = 2;
697: break;
698:
699: case LS1R:
700: screen->curgr = 1;
701: break;
702:
703: case DESIGNATE:
704: switch (ap->a_inters) {
705: case '(':
706: screen->gsets[0] = ap->a_final;
707: break;
708:
709: case ')':
710: screen->gsets[1] = ap->a_final;
711: break;
712:
713: case '*':
714: screen->gsets[2] = ap->a_final;
715: break;
716:
717: case '+':
718: screen->gsets[3] = ap->a_final;
719: break;
720:
721: case '#': /* special "hidden" sequence */
722: if (ap->a_final == '1')
723: fprintf(stderr, "avg call = %d char\n",
724: ctotal/ntotal);
725:
726: default:
727: break;
728: }
729: break;
730:
731: case DA1:
732: if (ap->a_param[0]==0) {
733: reply.a_type = CSI;
734: reply.a_pintro = '?';
735: reply.a_nparam = 1;
736: reply.a_param[0] = 6; /* VT102 */
737: reply.a_inters = 0;
738: reply.a_final = 'c';
739: unparseseq(&reply, screen->tx8bit, screen->respond);
740: }
741: break;
742:
743: case TBC:
744: if (ap->a_param[0]==0)
745: TabClear(term->tabs, screen->cur_col);
746: else if (ap->a_param[0] == 3)
747: TabZonk(term->tabs);
748: break;
749:
750: case SET:
751: modes(term, bitset);
752: break;
753:
754: case DECSET:
755: dpmodes(term, bitset);
756: break;
757:
758: case RST:
759: modes(term, bitclr);
760: break;
761:
762: case DECRST:
763: dpmodes(term, bitclr);
764: break;
765:
766: case SGR:
767: for (i=0; i<ap->a_nparam; ++i) {
768: switch (ap->a_param[i]) {
769: case 0:
770: term->flags &= ~(INVERSE|BOLD);
771: break;
772:
773: case 1:
774: case 4: /* Underscore, really */
775: case 5: /* Blink, really. */
776: term->flags |= BOLD;
777: break;
778:
779: case 7:
780: term->flags |= INVERSE;
781: }
782: }
783: break;
784:
785: case CPR:
786: if (ap->a_param[0]==5) {
787: reply.a_type = CSI;
788: reply.a_pintro = 0;
789: reply.a_nparam = 1;
790: reply.a_param[0] = 0;
791: reply.a_inters = 0;
792: reply.a_final = 'n';
793: unparseseq(&reply, screen->tx8bit, screen->respond);
794: break;
795: }
796: if (ap->a_param[0]==6) {
797: reply.a_type = CSI;
798: reply.a_pintro = 0;
799: reply.a_nparam = 2;
800: reply.a_param[0] = screen->cur_row+1;
801: reply.a_param[1] = screen->cur_col+1;
802: reply.a_inters = 0;
803: reply.a_final = 'R';
804: unparseseq(&reply, screen->tx8bit, screen->respond);
805: break;
806: }
807: break;
808:
809: case DECSTBM:
810: top = ap->a_param[0];
811: bot = ap->a_param[1];
812: if (top < 1)
813: top = 1;
814: if (bot > screen->max_row+1)
815: bot = screen->max_row+1;
816: if (bot > top) {
817: #ifdef JUMPSCROLL
818: if(screen->scroll_amt)
819: FlushScroll(screen);
820: #endif JUMPSCROLL
821: screen->top_marg = top-1;
822: screen->bot_marg = bot-1;
823: CursorSet(screen, 0, 0, term->flags);
824: }
825: break;
826:
827: case ICH:
828: InsertChar(screen, ap->a_param[0]);
829: break;
830:
831: case CUU:
832: CursorUp(screen, ap->a_param[0]);
833: break;
834:
835: case CUD:
836: CursorDown(screen, ap->a_param[0]);
837: break;
838:
839: case CUF:
840: CursorForward(screen, ap->a_param[0]);
841: break;
842:
843: case CUB:
844: CursorBack(screen, ap->a_param[0]);
845: break;
846:
847: case HVP:
848: case CUP:
849: row = ap->a_param[0];
850: col = ap->a_param[1];
851:
852: screen->cur_x = screen->cur_y = 0;
853: screen->TekAMode = 0;
854: CursorSet(screen, row-1, col-1, term->flags);
855: break;
856:
857: case ED:
858: switch (ap->a_param[0]) {
859: case 0: ClearBelow(screen);
860: break;
861:
862: case 1: ClearAbove(screen);
863: break;
864:
865: case 2: ClearScreen(screen);
866: if (screen->TekEmu)
867: TekErase(term);
868: break;
869: }
870: break;
871:
872: case EL:
873: switch (ap->a_param[0]) {
874: case 0: ClearRight(screen);
875: break;
876:
877: case 1: ClearLeft(screen);
878: break;
879:
880: case 2: ClearLine(screen);
881: break;
882: }
883: break;
884:
885: case IL:
886: InsertLine(screen, ap->a_param[0]);
887: break;
888:
889: case DL:
890: DeleteLine(screen, ap->a_param[0]);
891: break;
892:
893: case DCH:
894: DeleteChar(screen, ap->a_param[0]);
895: break;
896:
897: case DECALN:
898: text_ptr = text_buf;
899: text_cnt = TEXT_BUF_SIZE;
900: for (i=0; i<256; ++i) {
901: if (--text_cnt >= 0)
902: *text_ptr++ = i;
903: else {
904: flushbuf(screen, term->flags, text_ptr);
905: text_ptr = text_buf;
906: text_cnt = TEXT_BUF_SIZE-1;
907: *text_ptr++ = i;
908: }
909: }
910: flushbuf(screen, term->flags, text_ptr);
911: break;
912:
913: case TEKESCFF:
914: case TEKCSIUS:
915: CursorSet(screen, 0, 0, term->flags);
916: ClearScreen(screen);
917: TekErase(term);
918: break;
919:
920: case TEKESCSUB:
921: TekCursor(term);
922: break;
923:
924: case TEKESCINQ:
925: TekInq(term);
926: break;
927:
928: default:
929: Panic("unexpected dispatch (%d) encountered in doescape", kind);
930: break;
931: }
932: }
933:
934: /*
935: * this is a big switch of all the control characters we know how to handle.
936: * the cases of the switch have a corresponding entry in the ctable.
937: */
938: docontrol(term, c)
939: Terminal *term;
940: {
941: register Screen *screen = &term->screen;
942:
943: switch (ctable[c]) {
944: case CIGNORE:
945: break;
946:
947: case CBELL:
948: XFeep(0);
949: break;
950:
951: case CBACKSPACE:
952: CursorBack(screen, 1);
953: break;
954:
955: case CTAB:
956: screen->cur_col = TabNext(term->tabs, screen->cur_col);
957: if (screen->cur_col > screen->max_col)
958: screen->cur_col = screen->max_col;
959: break;
960:
961: case CLINEFEED: /* actually both VT and LF map here */
962: case CFORMFEED:
963: if (screen->TekAMode)
964: TekReset(term);
965: Index(screen, 1);
966: if (term->flags & LINEFEED)
967: CarriageReturn(screen);
968: break;
969:
970: case CRETURN:
971: if (screen->TekAMode)
972: TekReset(term);
973: CarriageReturn(screen);
974: break;
975:
976: case CLS1:
977: screen->curgl = 1;
978: break;
979:
980: case CLS0:
981: screen->curgl = 0;
982: break;
983:
984: case CCANCEL:
985: screen->mode = ANSInormal;
986: break;
987:
988: case CESC:
989: case CDCS:
990: case CCSI:
991: screen->ansi.a_type = c;
992: screen->ansi.a_pintro = 0;
993: screen->ansi.a_final = 0;
994: screen->ansi.a_inters = 0;
995: screen->ansi.a_nparam = 0;
996: screen->ansi.a_nastyf = 0;
997: screen->mode = ANSIparse;
998: break;
999:
1000: case CTEKINIT: /* come here from FS, GS, or RS */
1001: if (screen->TekEmu)
1002: TekInit(term, c);
1003: break;
1004:
1005: case CTEKALPH: /* US */
1006: break; /* just ignore; can only get to alpha */
1007: /* mode from Tek graphics mode */
1008:
1009: case CIND:
1010: Index(screen, 1);
1011: break;
1012:
1013: case CNEL:
1014: Index(screen, 1);
1015: CarriageReturn(screen);
1016: break;
1017:
1018: case CRI:
1019: RevIndex(screen, 1);
1020: break;
1021:
1022: case CSS2:
1023: screen->curss = 2;
1024: break;
1025:
1026: case CSS3:
1027: screen->curss = 3;
1028: break;
1029:
1030: default:
1031: Panic("unexpected char (0x%x) encountered in docontrol", c);
1032: break;
1033: }
1034: }
1035:
1036: /*
1037: * process ANSI modes set, reset
1038: */
1039: modes(term, func)
1040: Terminal *term;
1041: int (*func)();
1042: {
1043: register Screen *screen = &term->screen;
1044: register ANSI *ansi;
1045: register int i;
1046:
1047: ansi = &screen->ansi;
1048: for (i=0; i<ansi->a_nparam; ++i) {
1049: switch (ansi->a_param[i]) {
1050: case 4: /* IRM */
1051: (*func)(&term->flags, INSERT);
1052: break;
1053:
1054: case 20: /* LNM */
1055: (*func)(&term->flags, LINEFEED);
1056: break;
1057: }
1058: }
1059: }
1060:
1061: /*
1062: * process DEC private modes set, reset
1063: */
1064: dpmodes(term, func)
1065: Terminal *term;
1066: int (*func)();
1067: {
1068: register Screen *screen = &term->screen;
1069: register ANSI *ap;
1070: register int i;
1071:
1072: ap = &screen->ansi;
1073: for (i=0; i<ap->a_nparam; ++i) {
1074: switch (ap->a_param[i]) {
1075: case 1: /* DECCKM */
1076: (*func)(&term->keyboard.flags, CURSOR_APL);
1077: break;
1078:
1079: #ifdef JUMPSCROLL
1080: case 4: /* DECSCLM (slow scroll) */
1081: if (func == bitset) {
1082: screen->jumpscroll = 0;
1083: if (screen->scroll_amt)
1084: FlushScroll(screen);
1085: } else if (!screen->TekEmu)
1086: screen->jumpscroll = 1;
1087: (*func)(&term->flags, SMOOTHSCROLL);
1088: break;
1089: #endif JUMPSCROLL
1090: case 5: /* DECSCNM */
1091: i = term->flags;
1092: (*func)(&term->flags, REVERSE_VIDEO);
1093: if ((term->flags ^ i) & REVERSE_VIDEO)
1094: ReverseVideo(term);
1095: break;
1096:
1097: case 6: /* DECOM */
1098: (*func)(&term->flags, ORIGIN);
1099: CursorSet(screen, 0, 0, term->flags);
1100: break;
1101:
1102: case 7: /* DECAWM */
1103: (*func)(&term->flags, WRAPAROUND);
1104: break;
1105: case 9: /* MIT bogus sequence */
1106: (*func)(&screen->send_mouse_pos, 1);
1107: break;
1108: case 38: /* DECTEK */
1109: (*func)(&screen->TekEmu, 1);
1110: /*
1111: * probably need to do some work here to get
1112: * into or out of Tek emulation cleanly
1113: */
1114: break;
1115: }
1116: }
1117: }
1118:
1119: /*
1120: * set a bit in a word given a pointer to the word and a mask.
1121: */
1122: bitset(p, mask)
1123: int *p;
1124: {
1125: *p |= mask;
1126: }
1127:
1128: /*
1129: * clear a bit in a word given a pointer to the word and a mask.
1130: */
1131: bitclr(p, mask)
1132: int *p;
1133: {
1134: *p &= ~mask;
1135: }
1136:
1137: ReverseVideo (term)
1138: Terminal *term;
1139: {
1140: register Screen *screen = &term->screen;
1141: int tmp;
1142:
1143: XDefineCursor(screen->window,
1144: (term->flags & REVERSE_VIDEO) ? screen->rcurs : screen->curs);
1145: tmp = screen->background;
1146: if (screen->cursorcolor == screen->foreground)
1147: screen->cursorcolor = tmp;
1148: screen->background = screen->foreground;
1149: screen->foreground = tmp;
1150: XFreePixmap(screen->bgndtile);
1151: screen->bgndtile = XMakeTile(screen->background);
1152: if (screen->borderwidth &&
1153: screen->background < 2 &&
1154: screen->foreground < 2) {
1155: if (screen->bgndtile == BlackPixmap)
1156: screen->bordertile = WhitePixmap;
1157: else if (screen->bgndtile == WhitePixmap)
1158: screen->bordertile = BlackPixmap;
1159: XChangeBorder (screen->window, screen->bordertile);
1160: }
1161: XChangeBackground (screen->window, screen->bgndtile);
1162: XClear (screen->window);
1163: ScrnRefresh (screen, 0, 0, screen->max_row +1, screen->max_col + 1);
1164: if (screen->TekEmu) TekRefresh (term);
1165: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.