|
|
1.1 root 1: /*
2: * $Source: /u1/X/xterm/RCS/charproc.c,v $
3: * $Header: charproc.c,v 10.102 86/12/02 11:37:25 swick Exp $
4: */
5:
6: #include <X/mit-copyright.h>
7:
8: /* Copyright (c) 1985 Massachusetts Institute of Technology */
9: /* Copyright (c) 1985 Digital Equipment Corporation */
10:
11: /* charproc.c */
12:
13: #include <stdio.h>
14: #include <sgtty.h>
15: #include <ctype.h>
16: #include <errno.h>
17: #include <setjmp.h>
18: #include <sys/ioctl.h>
19: #include <sys/time.h>
20: #include <X/Xlib.h>
21: #include "scrollbar.h"
22: #include "ptyx.h"
23: #include "VTparse.h"
24: #include "data.h"
25: #include "error.h"
26: #ifdef MODEMENU
27: #include "menu.h"
28: #endif MODEMENU
29:
30: #define DEFAULT -1
31: #define TEXT_BUF_SIZE 256
32:
33: #define input() (bcnt-- > 0 ? *bptr++ : in_put())
34:
35: #ifndef lint
36: static char csrg_id[] = "@(#)charproc.c 1.6\t(Berkeley/CSRG)\t9/21/87";
37: static char sccs_id[] = "@(#)charproc.c\tX10/6.6B\t1/9/87";
38: #endif lint
39:
40: static long arg;
41: static int ch;
42: static int nparam;
43: static ANSI reply;
44: static int param[NPARAM];
45:
46: static unsigned long ctotal;
47: static unsigned long ntotal;
48: static jmp_buf vtjmpbuf;
49:
50: extern int groundtable[];
51: extern int csitable[];
52: extern int dectable[];
53: extern int eigtable[];
54: extern int esctable[];
55: extern int iestable[];
56: extern int igntable[];
57: extern int scrtable[];
58: extern int scstable[];
59:
60: VTparse()
61: {
62: register Screen *screen = &term.screen;
63: register int *parsestate = groundtable;
64: register int c;
65: register char *cp;
66: register int row, col, top, bot, scstype;
67: WindowInfo wininfo;
68: extern int bitset(), bitclr(), finput();
69:
70: if(setjmp(vtjmpbuf))
71: parsestate = groundtable;
72: for( ; ; )
73: switch(parsestate[c = input()]) {
74: case CASE_GROUND_STATE:
75: /* exit ignore mode */
76: parsestate = groundtable;
77: break;
78:
79: case CASE_IGNORE_STATE:
80: /* Ies: ignore anything else */
81: parsestate = igntable;
82: break;
83:
84: case CASE_IGNORE_ESC:
85: /* Ign: escape */
86: parsestate = iestable;
87: break;
88:
89: case CASE_IGNORE:
90: /* Ignore character */
91: break;
92:
93: case CASE_BELL:
94: /* bell */
95: Bell();
96: break;
97:
98: case CASE_BS:
99: /* backspace */
100: CursorBack(screen, 1);
101: break;
102:
103: case CASE_CR:
104: /* carriage return */
105: CarriageReturn(screen);
106: break;
107:
108: case CASE_ESC:
109: /* escape */
110: parsestate = esctable;
111: break;
112:
113: case CASE_VMOT:
114: /*
115: * form feed, line feed, vertical tab, but not in
116: * status line
117: */
118: if(!screen->instatus)
119: Index(screen, 1);
120: if (term.flags & LINEFEED)
121: CarriageReturn(screen);
122: if(screen->display->qlen > 0 ||
123: (ioctl(screen->display->fd, FIONREAD, &arg), arg) > 0)
124: xevents();
125: break;
126:
127: case CASE_TAB:
128: /* tab */
129: screen->cur_col = TabNext(term.tabs, screen->cur_col);
130: if (screen->cur_col > screen->max_col)
131: screen->cur_col = screen->max_col;
132: break;
133:
134: case CASE_SI:
135: screen->curgl = 0;
136: break;
137:
138: case CASE_SO:
139: screen->curgl = 1;
140: break;
141:
142: case CASE_SCR_STATE:
143: /* enter scr state */
144: parsestate = scrtable;
145: break;
146:
147: case CASE_SCS0_STATE:
148: /* enter scs state 0 */
149: scstype = 0;
150: parsestate = scstable;
151: break;
152:
153: case CASE_SCS1_STATE:
154: /* enter scs state 1 */
155: scstype = 1;
156: parsestate = scstable;
157: break;
158:
159: case CASE_SCS2_STATE:
160: /* enter scs state 2 */
161: scstype = 2;
162: parsestate = scstable;
163: break;
164:
165: case CASE_SCS3_STATE:
166: /* enter scs state 3 */
167: scstype = 3;
168: parsestate = scstable;
169: break;
170:
171: case CASE_ESC_IGNORE:
172: /* unknown escape sequence */
173: parsestate = eigtable;
174: break;
175:
176: case CASE_ESC_DIGIT:
177: /* digit in csi or dec mode */
178: if((row = param[nparam - 1]) == DEFAULT)
179: row = 0;
180: param[nparam - 1] = 10 * row + (c - '0');
181: break;
182:
183: case CASE_ESC_SEMI:
184: /* semicolon in csi or dec mode */
185: param[nparam++] = DEFAULT;
186: break;
187:
188: case CASE_DEC_STATE:
189: /* enter dec mode */
190: parsestate = dectable;
191: break;
192:
193: case CASE_ICH:
194: /* ICH */
195: if((c = param[0]) < 1)
196: c = 1;
197: InsertChar(screen, c);
198: parsestate = groundtable;
199: break;
200:
201: case CASE_CUU:
202: /* CUU */
203: /* only if not in status line */
204: if(!screen->instatus) {
205: if((c = param[0]) < 1)
206: c = 1;
207: CursorUp(screen, c);
208: }
209: parsestate = groundtable;
210: break;
211:
212: case CASE_CUD:
213: /* CUD */
214: /* only if not in status line */
215: if(!screen->instatus) {
216: if((c = param[0]) < 1)
217: c = 1;
218: CursorDown(screen, c);
219: }
220: parsestate = groundtable;
221: break;
222:
223: case CASE_CUF:
224: /* CUF */
225: if((c = param[0]) < 1)
226: c = 1;
227: CursorForward(screen, c);
228: parsestate = groundtable;
229: break;
230:
231: case CASE_CUB:
232: /* CUB */
233: if((c = param[0]) < 1)
234: c = 1;
235: CursorBack(screen, c);
236: parsestate = groundtable;
237: break;
238:
239: case CASE_CUP:
240: /* CUP | HVP */
241: /* only if not in status line */
242: if(!screen->instatus) {
243: if((row = param[0]) < 1)
244: row = 1;
245: if(nparam < 2 || (col = param[1]) < 1)
246: col = 1;
247: CursorSet(screen, row-1, col-1, term.flags);
248: }
249: parsestate = groundtable;
250: break;
251:
252: case CASE_ED:
253: /* ED */
254: switch (param[0]) {
255: case DEFAULT:
256: case 0:
257: if(screen->instatus)
258: ClearRight(screen);
259: else
260: ClearBelow(screen);
261: break;
262:
263: case 1:
264: if(screen->instatus)
265: ClearLeft(screen);
266: else
267: ClearAbove(screen);
268: break;
269:
270: case 2:
271: if(screen->instatus)
272: ClearLine(screen);
273: else
274: ClearScreen(screen);
275: break;
276: }
277: parsestate = groundtable;
278: break;
279:
280: case CASE_EL:
281: /* EL */
282: switch (param[0]) {
283: case DEFAULT:
284: case 0:
285: ClearRight(screen);
286: break;
287: case 1:
288: ClearLeft(screen);
289: break;
290: case 2:
291: ClearLine(screen);
292: break;
293: }
294: parsestate = groundtable;
295: break;
296:
297: case CASE_IL:
298: /* IL */
299: /* only if not in status line */
300: if(!screen->instatus) {
301: if((c = param[0]) < 1)
302: c = 1;
303: InsertLine(screen, c);
304: }
305: parsestate = groundtable;
306: break;
307:
308: case CASE_DL:
309: /* DL */
310: /* only if not in status line */
311: if(!screen->instatus) {
312: if((c = param[0]) < 1)
313: c = 1;
314: DeleteLine(screen, c);
315: }
316: parsestate = groundtable;
317: break;
318:
319: case CASE_DCH:
320: /* DCH */
321: if((c = param[0]) < 1)
322: c = 1;
323: DeleteChar(screen, c);
324: parsestate = groundtable;
325: break;
326:
327: case CASE_DA1:
328: /* DA1 */
329: if (param[0] <= 0) { /* less than means DEFAULT */
330: reply.a_type = CSI;
331: reply.a_pintro = '?';
332: reply.a_nparam = 2;
333: reply.a_param[0] = 1; /* VT102 */
334: reply.a_param[1] = 2; /* VT102 */
335: reply.a_inters = 0;
336: reply.a_final = 'c';
337: unparseseq(&reply, screen->respond);
338: }
339: parsestate = groundtable;
340: break;
341:
342: case CASE_TBC:
343: /* TBC */
344: if ((c = param[0]) <= 0) /* less than means default */
345: TabClear(term.tabs, screen->cur_col);
346: else if (c == 3)
347: TabZonk(term.tabs);
348: parsestate = groundtable;
349: break;
350:
351: case CASE_SET:
352: /* SET */
353: modes(&term, bitset);
354: parsestate = groundtable;
355: break;
356:
357: case CASE_RST:
358: /* RST */
359: modes(&term, bitclr);
360: parsestate = groundtable;
361: break;
362:
363: case CASE_SGR:
364: /* SGR */
365: for (c=0; c<nparam; ++c) {
366: switch (param[c]) {
367: case DEFAULT:
368: case 0:
369: term.flags &= ~(INVERSE|BOLD|UNDERLINE);
370: break;
371: case 1:
372: case 5: /* Blink, really. */
373: term.flags |= BOLD;
374: break;
375: case 4: /* Underscore */
376: term.flags |= UNDERLINE;
377: break;
378: case 7:
379: term.flags |= INVERSE;
380: }
381: }
382: parsestate = groundtable;
383: break;
384:
385: case CASE_CPR:
386: /* CPR */
387: if ((c = param[0]) == 5) {
388: reply.a_type = CSI;
389: reply.a_pintro = 0;
390: reply.a_nparam = 1;
391: reply.a_param[0] = 0;
392: reply.a_inters = 0;
393: reply.a_final = 'n';
394: unparseseq(&reply, screen->respond);
395: } else if (c == 6) {
396: reply.a_type = CSI;
397: reply.a_pintro = 0;
398: reply.a_nparam = 2;
399: reply.a_param[0] = screen->cur_row+1;
400: reply.a_param[1] = screen->cur_col+1;
401: reply.a_inters = 0;
402: reply.a_final = 'R';
403: unparseseq(&reply, screen->respond);
404: }
405: parsestate = groundtable;
406: break;
407:
408: case CASE_DECSTBM:
409: /* DECSTBM */
410: /* only if not in status line */
411: if(!screen->instatus) {
412: if((top = param[0]) < 1)
413: top = 1;
414: if(nparam < 2 || (bot = param[1]) == DEFAULT
415: || bot > screen->max_row + 1
416: || bot == 0)
417: bot = screen->max_row+1;
418: if (bot > top) {
419: if(screen->scroll_amt)
420: FlushScroll(screen);
421: screen->top_marg = top-1;
422: screen->bot_marg = bot-1;
423: CursorSet(screen, 0, 0, term.flags);
424: }
425: }
426: parsestate = groundtable;
427: break;
428:
429: case CASE_SUN_EMU:
430: /* sub-set of sun tty emulation */
431: switch(param[0]) {
432: case 3: /* move window */
433: if(nparam == 3) {
434: XMoveWindow(VWindow(screen), param[2],
435: param[1]);
436: XSync(FALSE); /* synchronize */
437: if(QLength() > 0)
438: xevents();
439: }
440: break;
441: case 4: /* resize window (pixels) */
442: if(nparam == 3) {
443: XChangeWindow (VWindow(screen), param[1],
444: param[2]);
445: XSync(FALSE); /* synchronize */
446: if(QLength() > 0)
447: xevents();
448: }
449: break;
450: case 5: /* raise window */
451: XRaiseWindow(VWindow(screen));
452: break;
453: case 6: /* lower window */
454: XLowerWindow(VWindow(screen));
455: break;
456: case 7: /* redisplay window */
457: Redraw();
458: break;
459: case 8: /* resize window (rows and columns) */
460: if(nparam == 3) {
461: XChangeWindow (VWindow(screen),
462: FontWidth(screen) * param[2] +
463: 2 * screen->border + screen->scrollbar,
464: FontHeight(screen) * param[1] +
465: screen->statusheight + Titlebar(screen)
466: + 2 * screen->border);
467: XSync(FALSE); /* synchronize */
468: if(QLength() > 0)
469: xevents();
470: }
471: break;
472: case 13: /* send window position */
473: XQueryWindow(VWindow(screen), &wininfo);
474: reply.a_type = CSI;
475: reply.a_pintro = 0;
476: reply.a_nparam = 3;
477: reply.a_param[0] = 3;
478: reply.a_param[1] = wininfo.y;
479: reply.a_param[2] = wininfo.x;
480: reply.a_inters = 0;
481: reply.a_final = 't';
482: unparseseq(&reply, screen->respond);
483: break;
484: case 14: /* send window size (pixels) */
485: reply.a_type = CSI;
486: reply.a_pintro = 0;
487: reply.a_nparam = 3;
488: reply.a_param[0] = 4;
489: reply.a_param[1] = (screen->max_col + 1) *
490: FontWidth(screen) + 2 * screen->border +
491: screen->scrollbar;
492: reply.a_param[2] = (screen->max_row + 1) *
493: FontHeight(screen) + screen->statusheight +
494: Titlebar(screen) + 2 * screen->border;
495: reply.a_inters = 0;
496: reply.a_final = 't';
497: unparseseq(&reply, screen->respond);
498: break;
499: case 18: /* send window size (rows and cols) */
500: reply.a_type = CSI;
501: reply.a_pintro = 0;
502: reply.a_nparam = 3;
503: reply.a_param[0] = 8;
504: reply.a_param[1] = screen->max_row + 1;
505: reply.a_param[2] = screen->max_col + 1;
506: reply.a_inters = 0;
507: reply.a_final = 't';
508: unparseseq(&reply, screen->respond);
509: break;
510: }
511: parsestate = groundtable;
512: break;
513:
514: case CASE_DECREQTPARM:
515: /* DECREQTPARM */
516: if ((c = param[0]) == DEFAULT)
517: c = 0;
518: if (c == 0 || c == 1) {
519: reply.a_type = CSI;
520: reply.a_pintro = 0;
521: reply.a_nparam = 7;
522: reply.a_param[0] = c + 2;
523: reply.a_param[1] = 1; /* no parity */
524: reply.a_param[2] = 1; /* eight bits */
525: reply.a_param[3] = 112; /* transmit 9600 baud */
526: reply.a_param[4] = 112; /* receive 9600 baud */
527: reply.a_param[5] = 1; /* clock multiplier ? */
528: reply.a_param[6] = 0; /* STP flags ? */
529: reply.a_inters = 0;
530: reply.a_final = 'x';
531: unparseseq(&reply, screen->respond);
532: }
533: parsestate = groundtable;
534: break;
535:
536: case CASE_DECSET:
537: /* DECSET */
538: dpmodes(&term, bitset);
539: parsestate = groundtable;
540: if(screen->TekEmu)
541: return;
542: break;
543:
544: case CASE_DECRST:
545: /* DECRST */
546: dpmodes(&term, bitclr);
547: parsestate = groundtable;
548: break;
549:
550: case CASE_HIDDEN:
551: /* special "hidden" sequence */
552: fprintf(stderr, "avg call = %ld char\n", ctotal/ntotal);
553: parsestate = groundtable;
554: break;
555:
556: case CASE_DECALN:
557: /* DECALN */
558: if(screen->cursor_state)
559: HideCursor();
560: for(row = screen->max_row ; row >= 0 ; row--) {
561: bzero(screen->buf[2 * row + 1],
562: col = screen->max_col + 1);
563: for(cp = screen->buf[2 * row] ; col > 0 ; col--)
564: *cp++ = 'E';
565: }
566: ScrnRefresh(screen, 0, 0, screen->max_row + 1,
567: screen->max_col + 1);
568: parsestate = groundtable;
569: break;
570:
571: case CASE_GSETS:
572: screen->gsets[scstype] = c;
573: parsestate = groundtable;
574: break;
575:
576: case CASE_DECSC:
577: /* DECSC */
578: CursorSave(&term, &screen->sc);
579: parsestate = groundtable;
580: break;
581:
582: case CASE_DECRC:
583: /* DECRC */
584: CursorRestore(&term, &screen->sc);
585: parsestate = groundtable;
586: break;
587:
588: case CASE_DECKPAM:
589: /* DECKPAM */
590: term.keyboard.flags |= KYPD_APL;
591: parsestate = groundtable;
592: break;
593:
594: case CASE_DECKPNM:
595: /* DECKPNM */
596: term.keyboard.flags &= ~KYPD_APL;
597: parsestate = groundtable;
598: break;
599:
600: case CASE_IND:
601: /* IND */
602: /* only if not in status line */
603: if(!screen->instatus)
604: Index(screen, 1);
605: if(screen->display->qlen > 0 ||
606: (ioctl(screen->display->fd, FIONREAD, &arg), arg) > 0)
607: xevents();
608: parsestate = groundtable;
609: break;
610:
611: case CASE_NEL:
612: /* NEL */
613: /* only if not in status line */
614: if(!screen->instatus)
615: Index(screen, 1);
616: CarriageReturn(screen);
617: if(screen->display->qlen > 0 ||
618: (ioctl(screen->display->fd, FIONREAD, &arg), arg) > 0)
619: xevents();
620: parsestate = groundtable;
621: break;
622:
623: case CASE_HTS:
624: /* HTS */
625: TabSet(term.tabs, screen->cur_col);
626: parsestate = groundtable;
627: break;
628:
629: case CASE_RI:
630: /* RI */
631: /* only if not in status line */
632: if(!screen->instatus)
633: RevIndex(screen, 1);
634: parsestate = groundtable;
635: break;
636:
637: case CASE_SS2:
638: /* SS2 */
639: screen->curss = 2;
640: parsestate = groundtable;
641: break;
642:
643: case CASE_SS3:
644: /* SS3 */
645: screen->curss = 3;
646: parsestate = groundtable;
647: break;
648:
649: case CASE_CSI_STATE:
650: /* enter csi state */
651: nparam = 1;
652: param[0] = DEFAULT;
653: parsestate = csitable;
654: break;
655:
656: case CASE_OSC:
657: /* do osc escapes */
658: do_osc(finput);
659: parsestate = groundtable;
660: break;
661:
662: case CASE_RIS:
663: /* RIS */
664: VTReset(TRUE);
665: parsestate = groundtable;
666: break;
667:
668: case CASE_LS2:
669: /* LS2 */
670: screen->curgl = 2;
671: parsestate = groundtable;
672: break;
673:
674: case CASE_LS3:
675: /* LS3 */
676: screen->curgl = 3;
677: parsestate = groundtable;
678: break;
679:
680: case CASE_LS3R:
681: /* LS3R */
682: screen->curgr = 3;
683: parsestate = groundtable;
684: break;
685:
686: case CASE_LS2R:
687: /* LS2R */
688: screen->curgr = 2;
689: parsestate = groundtable;
690: break;
691:
692: case CASE_LS1R:
693: /* LS1R */
694: screen->curgr = 1;
695: parsestate = groundtable;
696: break;
697:
698: case CASE_TO_STATUS:
699: if((c = param[0]) < 1)
700: c = 1;
701: ToStatus(c - 1);
702: parsestate = groundtable;
703: break;
704:
705: case CASE_FROM_STATUS:
706: FromStatus();
707: parsestate = groundtable;
708: break;
709:
710: case CASE_SHOW_STATUS:
711: ShowStatus();
712: parsestate = groundtable;
713: break;
714:
715: case CASE_HIDE_STATUS:
716: HideStatus();
717: parsestate = groundtable;
718: break;
719:
720: case CASE_ERASE_STATUS:
721: EraseStatus();
722: parsestate = groundtable;
723: break;
724:
725: case CASE_XTERM_SAVE:
726: savemodes(&term);
727: parsestate = groundtable;
728: break;
729:
730: case CASE_XTERM_RESTORE:
731: restoremodes(&term);
732: parsestate = groundtable;
733: break;
734:
735: case CASE_PRINT:
736: /* printable characters */
737: top = bcnt > TEXT_BUF_SIZE ? TEXT_BUF_SIZE : bcnt;
738: cp = bptr;
739: *--bptr = c;
740: while(top > 0 && isprint(*cp)) {
741: top--;
742: bcnt--;
743: cp++;
744: }
745: if(screen->curss) {
746: dotext(screen, term.flags,
747: screen->gsets[screen->curss], bptr, bptr + 1);
748: screen->curss = 0;
749: bptr++;
750: }
751: if(bptr < cp)
752: dotext(screen, term.flags,
753: screen->gsets[screen->curgl], bptr, cp);
754: bptr = cp;
755: break;
756: }
757: }
758:
759: finput()
760: {
761: return(input());
762: }
763:
764: static int select_mask;
765:
766: in_put()
767: {
768: register Screen *screen = &term.screen;
769: register char *cp;
770: register int i;
771:
772: select_mask = pty_mask; /* force initial read */
773: for( ; ; ) {
774: if(select_mask & pty_mask) {
775: if(screen->logging)
776: FlushLog(screen);
777: if((bcnt = read(screen->respond, bptr = buffer,
778: BUF_SIZE)) < 0) {
779: if(errno == EIO && am_slave)
780: exit(0);
781: else if(errno != EWOULDBLOCK)
782: Panic(
783: "input: read returned unexpected error (%d)\n",
784: errno);
785: } else if(bcnt == 0)
786: Panic("input: read returned zero\n");
787: else {
788: /* strip parity bit */
789: for(i = bcnt, cp = bptr ; i > 0 ; i--)
790: *cp++ &= CHAR;
791: if(screen->sb && screen->scrollinput &&
792: screen->topline < 0)
793: ScrollToBottom(screen->sb);
794: if(screen->icon_show && !screen->iconinput) {
795: screen->iconinput = TRUE;
796: IconBox(screen);
797: }
798: break;
799: }
800: }
801: if(screen->scroll_amt)
802: FlushScroll(screen);
803: if(screen->cursor_set && (screen->cursor_col != screen->cur_col
804: || screen->cursor_row != screen->cur_row)) {
805: if(screen->cursor_state)
806: HideCursor();
807: ShowCursor();
808: } else if(screen->cursor_set != screen->cursor_state) {
809: if(screen->cursor_set)
810: ShowCursor();
811: else
812: HideCursor();
813: }
814:
815: /* Window select/unselect */
816: if (doonalarmcode)
817: onalarmcode();
818:
819: if(QLength())
820: select_mask = X_mask;
821: else {
822: XFlush();
823: select_mask = Select_mask;
824: if((i = select(max_plus1, &select_mask, NULL, NULL,
825: screen->timeout)) < 0){
826: if (errno != EINTR)
827: SysError(ERROR_SELECT);
828: continue;
829: } else if(i == 0) {
830: if(GetButtonState(screen->sb) & HILITED)
831: WindowScroll(screen,
832: ButtonRegion(screen->sb));
833: screen->timeout->tv_usec = STEPTIME;
834: continue;
835: }
836: }
837: if(select_mask & X_mask)
838: xevents();
839: }
840: bcnt--;
841: return(*bptr++);
842: }
843:
844: /*
845: * process a string of characters according to the character set indicated
846: * by charset. worry about end of line conditions (wraparound if selected).
847: */
848: dotext(screen, flags, charset, buf, ptr)
849: register Screen *screen;
850: unsigned flags;
851: char charset;
852: char *buf;
853: char *ptr;
854: {
855: register char *s;
856: register int len;
857: register int n;
858: register int next_col;
859:
860: switch (charset) {
861: case 'A': /* United Kingdom set */
862: for (s=buf; s<ptr; ++s)
863: if (*s == '#')
864: *s = '\036'; /* UK pound sign */
865: break;
866:
867: case 'B': /* ASCII set */
868: break;
869:
870: case '0': /* special graphics (line drawing) */
871: for (s=buf; s<ptr; ++s)
872: if (*s>=0x5f && *s<=0x7e)
873: *s = *s == 0x5f ? 0x7f : *s - 0x5f;
874: break;
875:
876: default: /* any character sets we don't recognize */
877: return;
878: }
879:
880: len = ptr - buf;
881: ptr = buf;
882: while (len > 0) {
883: n = screen->max_col-screen->cur_col+1;
884: if (n <= 1) {
885: if (screen->do_wrap && (flags&WRAPAROUND) &&
886: !screen->instatus) {
887: Index(screen, 1);
888: screen->cur_col = 0;
889: screen->do_wrap = 0;
890: n = screen->max_col+1;
891: } else
892: n = 1;
893: }
894: if (len < n)
895: n = len;
896: next_col = screen->cur_col + n;
897: WriteText(screen, ptr, n, flags);
898: /*
899: * the call to WriteText updates screen->cur_col.
900: * If screen->cur_col != next_col, we must have
901: * hit the right margin, so set the do_wrap flag.
902: */
903: screen->do_wrap = (screen->cur_col < next_col);
904: len -= n;
905: ptr += n;
906: }
907: }
908:
909: /*
910: * write a string str of length len onto the screen at
911: * the current cursor position. update cursor position.
912: */
913: WriteText(screen, str, len, flags)
914: register Screen *screen;
915: register char *str;
916: register int len;
917: unsigned flags;
918: {
919: register int pix, cx, cy;
920: register unsigned fgs = flags;
921: Font fnt;
922:
923: if(screen->instatus && screen->reversestatus)
924: fgs ^= INVERSE;
925: if(screen->cur_row - screen->topline <= screen->max_row ||
926: screen->instatus) {
927: /*
928: if(screen->cur_row == screen->cursor_row && screen->cur_col <=
929: screen->cursor_col && screen->cursor_col <= screen->cur_col + len - 1)
930: screen->cursor_state = OFF;
931: */
932: if(screen->cursor_state)
933: HideCursor();
934: fnt = ActiveIcon(screen) ? screen->fnt_icon
935: : (fgs & BOLD) ? screen->fnt_bold : screen->fnt_norm;
936: if (fgs & INSERT)
937: InsertChar(screen, len);
938: if (!(AddToRefresh(screen))) {
939: if(screen->scroll_amt)
940: FlushScroll(screen);
941: cx = CursorX(screen, screen->cur_col);
942: cy = CursorY(screen, screen->cur_row);
943: if (screen->show || ActiveIcon(screen)) {
944: if (fgs & INVERSE)
945: XText(VWindow(screen), cx, cy, str, len, fnt,
946: pix = screen->background, screen->foreground);
947: else
948: XText(VWindow(screen), cx, cy, str, len, fnt,
949: pix = screen->foreground, screen->background);
950: if((fgs & BOLD) && screen->enbolden)
951: XTextMask(VWindow(screen), cx + 1, cy, str, len, fnt, pix);
952: if(fgs & UNDERLINE) {
953: cy += FontHeight(screen) - 2;
954: XLine(VWindow(screen), cx, cy, cx + len * FontWidth(screen),
955: cy, 1, 1, pix, GXcopy, AllPlanes);
956: }
957: }
958: /*
959: * the following statements compile data to compute the average
960: * number of characters written on each call to XText. The data
961: * may be examined via the use of a "hidden" escape sequence.
962: */
963: ctotal += len;
964: ++ntotal;
965: }
966: }
967: ScreenWrite(screen, str, flags, len);
968: CursorForward(screen, len);
969: }
970:
971: /*
972: * process ANSI modes set, reset
973: */
974: modes(term, func)
975: Terminal *term;
976: int (*func)();
977: {
978: register Screen *screen = &term->screen;
979: register int i;
980:
981: for (i=0; i<nparam; ++i) {
982: switch (param[i]) {
983: case 4: /* IRM */
984: (*func)(&term->flags, INSERT);
985: break;
986:
987: case 20: /* LNM */
988: (*func)(&term->flags, LINEFEED);
989: break;
990: }
991: }
992: }
993:
994: /*
995: * process DEC private modes set, reset
996: */
997: dpmodes(term, func)
998: Terminal *term;
999: int (*func)();
1000: {
1001: register Screen *screen = &term->screen;
1002: register int i, j;
1003: extern int bitset();
1004:
1005: for (i=0; i<nparam; ++i) {
1006: switch (param[i]) {
1007: case 1: /* DECCKM */
1008: (*func)(&term->keyboard.flags, CURSOR_APL);
1009: break;
1010: case 3: /* DECCOLM */
1011: if(screen->c132) {
1012: ClearScreen(screen);
1013: CursorSet(screen, 0, 0, term->flags);
1014: if((j = func == bitset ? 132 : 80) !=
1015: ((term->flags & IN132COLUMNS) ? 132 : 80) ||
1016: j != screen->max_col + 1) {
1017: XChangeWindow (VWindow(screen),
1018: FontWidth(screen) * j + 2*screen->border
1019: + screen->scrollbar,
1020: FontHeight(screen) * (screen->max_row
1021: + 1) + screen->statusheight +
1022: Titlebar(screen) + 2 * screen->border);
1023: XSync(FALSE); /* synchronize */
1024: if(QLength() > 0)
1025: xevents();
1026: }
1027: (*func)(&term->flags, IN132COLUMNS);
1028: }
1029: break;
1030: case 4: /* DECSCLM (slow scroll) */
1031: if (func == bitset) {
1032: screen->jumpscroll = 0;
1033: if (screen->scroll_amt)
1034: FlushScroll(screen);
1035: } else
1036: screen->jumpscroll = 1;
1037: (*func)(&term->flags, SMOOTHSCROLL);
1038: break;
1039: case 5: /* DECSCNM */
1040: j = term->flags;
1041: (*func)(&term->flags, REVERSE_VIDEO);
1042: if ((term->flags ^ j) & REVERSE_VIDEO)
1043: ReverseVideo(term);
1044: break;
1045:
1046: case 6: /* DECOM */
1047: (*func)(&term->flags, ORIGIN);
1048: CursorSet(screen, 0, 0, term->flags);
1049: break;
1050:
1051: case 7: /* DECAWM */
1052: (*func)(&term->flags, WRAPAROUND);
1053: break;
1054: case 8: /* DECARM */
1055: j = term->flags;
1056: (*func)(&term->flags, AUTOREPEAT);
1057: if ((term->flags ^ j) & AUTOREPEAT)
1058: if(term->flags & AUTOREPEAT)
1059: XAutoRepeatOn();
1060: else
1061: XAutoRepeatOff();
1062: break;
1063: case 9: /* MIT bogus sequence */
1064: (*func)(&screen->send_mouse_pos, 1);
1065: break;
1066: case 38: /* DECTEK */
1067: if(func == bitset & !(screen->inhibit & I_TEK)) {
1068: if(screen->logging) {
1069: FlushLog(screen);
1070: screen->logstart = Tbuffer;
1071: }
1072: screen->TekEmu = TRUE;
1073: }
1074: break;
1075: case 40: /* 132 column mode */
1076: (*func)(&screen->c132, 1);
1077: break;
1078: case 41: /* curses hack */
1079: (*func)(&screen->curses, 1);
1080: break;
1081: case 42: /* scrollbar */
1082: if(func == bitset)
1083: ScrollBarOn(screen, TRUE, FALSE);
1084: else
1085: ScrollBarOff(screen);
1086: break;
1087: case 43: /* lines off top */
1088: if(screen->sb)
1089: SetSaveState(screen->sb, (func == bitset));
1090: break;
1091: case 44: /* margin bell */
1092: (*func)(&screen->marginbell, 1);
1093: if(!screen->marginbell)
1094: screen->bellarmed = -1;
1095: break;
1096: case 45: /* reverse wraparound */
1097: (*func)(&term->flags, REVERSEWRAP);
1098: break;
1099: case 46: /* logging */
1100: if(func == bitset)
1101: StartLog(screen);
1102: else
1103: CloseLog(screen);
1104: break;
1105: case 47: /* alternate buffer */
1106: if(func == bitset)
1107: ToAlternate(screen);
1108: else
1109: FromAlternate(screen);
1110: break;
1111: case 48: /* reverse status line */
1112: j = screen->reversestatus;
1113: (*func)(&screen->reversestatus, 1);
1114: if(j != screen->reversestatus)
1115: ScrnRefresh(screen, screen->max_row + 1, 0, 1,
1116: screen->max_col + 1);
1117: break;
1118: case 49: /* page mode */
1119: j = screen->pagemode;
1120: (*func)(&screen->pagemode, 1);
1121: if(!j && screen->pagemode)
1122: screen->pagecnt = 0;
1123: break;
1124: }
1125: }
1126: }
1127:
1128: /*
1129: * process xterm private modes save
1130: */
1131: savemodes(term)
1132: Terminal *term;
1133: {
1134: register Screen *screen = &term->screen;
1135: register int i;
1136:
1137: for (i = 0; i < nparam; i++) {
1138: switch (param[i]) {
1139: case 1: /* DECCKM */
1140: screen->save_modes[0] = term->keyboard.flags &
1141: CURSOR_APL;
1142: break;
1143: case 3: /* DECCOLM */
1144: if(screen->c132)
1145: screen->save_modes[1] = term->flags &
1146: IN132COLUMNS;
1147: break;
1148: case 4: /* DECSCLM (slow scroll) */
1149: screen->save_modes[2] = term->flags & SMOOTHSCROLL;
1150: break;
1151: case 5: /* DECSCNM */
1152: screen->save_modes[3] = term->flags & REVERSE_VIDEO;
1153: break;
1154: case 6: /* DECOM */
1155: screen->save_modes[4] = term->flags & ORIGIN;
1156: break;
1157:
1158: case 7: /* DECAWM */
1159: screen->save_modes[5] = term->flags & WRAPAROUND;
1160: break;
1161: case 8: /* DECARM */
1162: screen->save_modes[6] = term->flags & AUTOREPEAT;
1163: break;
1164: case 9: /* MIT bogus sequence */
1165: screen->save_modes[7] = screen->send_mouse_pos;
1166: break;
1167: case 40: /* 132 column mode */
1168: screen->save_modes[8] = screen->c132;
1169: break;
1170: case 41: /* curses hack */
1171: screen->save_modes[9] = screen->curses;
1172: break;
1173: case 42: /* scrollbar */
1174: screen->save_modes[10] = screen->scrollbar;
1175: break;
1176: case 43: /* lines off top */
1177: if(screen->sb)
1178: screen->save_modes[11] =
1179: GetSaveState(screen->sb);
1180: break;
1181: case 44: /* margin bell */
1182: screen->save_modes[12] = screen->marginbell;
1183: break;
1184: case 45: /* reverse wraparound */
1185: screen->save_modes[13] = term->flags & REVERSEWRAP;
1186: break;
1187: case 46: /* logging */
1188: screen->save_modes[14] = screen->logging;
1189: break;
1190: case 47: /* alternate buffer */
1191: screen->save_modes[15] = screen->alternate;
1192: break;
1193: case 48: /* reverse status line */
1194: screen->save_modes[16] = screen->reversestatus;
1195: break;
1196: case 49: /* page mode */
1197: screen->save_modes[17] = screen->pagemode;
1198: screen->save_modes[18] = screen->pagecnt;
1199: break;
1200: }
1201: }
1202: }
1203:
1204: /*
1205: * process xterm private modes restore
1206: */
1207: restoremodes(term)
1208: Terminal *term;
1209: {
1210: register Screen *screen = &term->screen;
1211: register int i, j;
1212:
1213: for (i = 0; i < nparam; i++) {
1214: switch (param[i]) {
1215: case 1: /* DECCKM */
1216: term->keyboard.flags &= ~CURSOR_APL;
1217: term->keyboard.flags |= screen->save_modes[0] &
1218: CURSOR_APL;
1219: break;
1220: case 3: /* DECCOLM */
1221: if(screen->c132) {
1222: ClearScreen(screen);
1223: CursorSet(screen, 0, 0, term->flags);
1224: if((j = (screen->save_modes[1] & IN132COLUMNS)
1225: ? 132 : 80) != ((term->flags & IN132COLUMNS)
1226: ? 132 : 80) || j != screen->max_col + 1) {
1227: XChangeWindow (VWindow(screen),
1228: FontWidth(screen) * j + 2*screen->border
1229: + screen->scrollbar,
1230: FontHeight(screen) * (screen->max_row
1231: + 1) + screen->statusheight +
1232: Titlebar(screen) + 2 * screen->border);
1233: XSync(FALSE); /* synchronize */
1234: if(QLength() > 0)
1235: xevents();
1236: }
1237: term->flags &= ~IN132COLUMNS;
1238: term->flags |= screen->save_modes[1] &
1239: IN132COLUMNS;
1240: }
1241: break;
1242: case 4: /* DECSCLM (slow scroll) */
1243: if (screen->save_modes[2] & SMOOTHSCROLL) {
1244: screen->jumpscroll = 0;
1245: if (screen->scroll_amt)
1246: FlushScroll(screen);
1247: } else
1248: screen->jumpscroll = 1;
1249: term->flags &= ~SMOOTHSCROLL;
1250: term->flags |= screen->save_modes[2] & SMOOTHSCROLL;
1251: break;
1252: case 5: /* DECSCNM */
1253: if((screen->save_modes[3] ^ term->flags) &
1254: REVERSE_VIDEO) {
1255: term->flags &= ~REVERSE_VIDEO;
1256: term->flags |= screen->save_modes[3] &
1257: REVERSE_VIDEO;
1258: ReverseVideo(term);
1259: }
1260: break;
1261: case 6: /* DECOM */
1262: term->flags &= ~ORIGIN;
1263: term->flags |= screen->save_modes[4] & ORIGIN;
1264: CursorSet(screen, 0, 0, term->flags);
1265: break;
1266:
1267: case 7: /* DECAWM */
1268: term->flags &= ~WRAPAROUND;
1269: term->flags |= screen->save_modes[5] & WRAPAROUND;
1270: break;
1271: case 8: /* DECARM */
1272: if((screen->save_modes[6] ^ term->flags) & AUTOREPEAT) {
1273: term->flags &= ~REVERSE_VIDEO;
1274: term->flags |= screen->save_modes[6] &
1275: REVERSE_VIDEO;
1276: if(term->flags & AUTOREPEAT)
1277: XAutoRepeatOn();
1278: else
1279: XAutoRepeatOff();
1280: }
1281: break;
1282: case 9: /* MIT bogus sequence */
1283: screen->send_mouse_pos = screen->save_modes[7];
1284: break;
1285: case 40: /* 132 column mode */
1286: screen->c132 = screen->save_modes[8];
1287: break;
1288: case 41: /* curses hack */
1289: screen->curses = screen->save_modes[9];
1290: break;
1291: case 42: /* scrollbar */
1292: if(screen->save_modes[10])
1293: ScrollBarOn(screen, TRUE, FALSE);
1294: else
1295: ScrollBarOff(screen);
1296: break;
1297: case 43: /* lines off top */
1298: if(screen->sb)
1299: SetSaveState(screen->sb,screen->save_modes[11]);
1300: break;
1301: case 44: /* margin bell */
1302: if(!(screen->marginbell = screen->save_modes[12]))
1303: screen->bellarmed = -1;
1304: break;
1305: case 45: /* reverse wraparound */
1306: term->flags &= ~REVERSEWRAP;
1307: term->flags |= screen->save_modes[13] & REVERSEWRAP;
1308: break;
1309: case 46: /* logging */
1310: if(screen->save_modes[14])
1311: StartLog(screen);
1312: else
1313: CloseLog(screen);
1314: break;
1315: case 47: /* alternate buffer */
1316: if(screen->save_modes[15])
1317: ToAlternate(screen);
1318: else
1319: FromAlternate(screen);
1320: break;
1321: case 48: /* reverse status line */
1322: if(screen->save_modes[16] != screen->reversestatus) {
1323: screen->reversestatus =
1324: screen->save_modes[16];
1325: ScrnRefresh(screen, screen->max_row + 1, 0, 1,
1326: screen->max_col + 1);
1327: }
1328: break;
1329: case 49: /* page mode */
1330: screen->pagemode = screen->save_modes[17];
1331: screen->pagecnt = screen->save_modes[18];
1332: break;
1333: }
1334: }
1335: }
1336:
1337: /*
1338: * set a bit in a word given a pointer to the word and a mask.
1339: */
1340: bitset(p, mask)
1341: int *p;
1342: {
1343: *p |= mask;
1344: }
1345:
1346: /*
1347: * clear a bit in a word given a pointer to the word and a mask.
1348: */
1349: bitclr(p, mask)
1350: int *p;
1351: {
1352: *p &= ~mask;
1353: }
1354:
1355: unparseseq(ap, fd)
1356: register ANSI *ap;
1357: {
1358: register int c;
1359: register int i;
1360: register int inters;
1361:
1362: c = ap->a_type;
1363: if (c>=0x80 && c<=0x9F) {
1364: unparseputc(ESC, fd);
1365: c -= 0x40;
1366: }
1367: unparseputc(c, fd);
1368: c = ap->a_type;
1369: if (c==ESC || c==DCS || c==CSI || c==OSC || c==PM || c==APC) {
1370: if (ap->a_pintro != 0)
1371: unparseputc(ap->a_pintro, fd);
1372: for (i=0; i<ap->a_nparam; ++i) {
1373: if (i != 0)
1374: unparseputc(';', fd);
1375: unparseputn(ap->a_param[i], fd);
1376: }
1377: inters = ap->a_inters;
1378: for (i=3; i>=0; --i)
1379: c = (inters >> (8*i)) & 0xff;
1380: if (c != 0)
1381: unparseputc(c, fd);
1382: unparseputc(ap->a_final, fd);
1383: }
1384: }
1385:
1386: unparseputn(n, fd)
1387: unsigned int n;
1388: {
1389: unsigned int q;
1390:
1391: q = n/10;
1392: if (q != 0)
1393: unparseputn(q, fd);
1394: unparseputc((n%10) + '0', fd);
1395: }
1396:
1397: unparseputc(c, fd)
1398: {
1399: char buf[2];
1400: register i = 1;
1401: extern Terminal term;
1402:
1403: if((buf[0] = c) == '\r' && (term.flags & LINEFEED)) {
1404: buf[1] = '\n';
1405: i++;
1406: }
1407: if (write(fd, buf, i) != i)
1408: Panic("unparseputc: error writing character\n", 0);
1409: }
1410:
1411: static int alt_pagecnt;
1412: static int alt_pagemode;
1413: static int alt_saving;
1414:
1415: ToAlternate(screen)
1416: register Screen *screen;
1417: {
1418: extern ScrnBuf Allocate();
1419:
1420: if(screen->alternate)
1421: return;
1422: if(!screen->altbuf)
1423: screen->altbuf = Allocate(screen->max_row + 1, screen->max_col
1424: + 1);
1425: if(screen->sb) {
1426: alt_saving = GetSaveState(screen->sb);
1427: SetSaveState(screen->sb, FALSE);
1428: } else
1429: alt_saving = TRUE;
1430: if(alt_pagemode = screen->pagemode)
1431: alt_pagecnt = screen->pagecnt;
1432: screen->pagemode = FALSE;
1433: SwitchBufs(screen);
1434: screen->alternate = TRUE;
1435: }
1436:
1437: FromAlternate(screen)
1438: register Screen *screen;
1439: {
1440: if(!screen->alternate)
1441: return;
1442: screen->alternate = FALSE;
1443: if(screen->sb)
1444: SetSaveState(screen->sb, alt_saving);
1445: if(screen->pagemode = alt_pagemode)
1446: screen->pagecnt = alt_pagecnt;
1447: SwitchBufs(screen);
1448: }
1449:
1450: SwitchBufs(screen)
1451: register Screen *screen;
1452: {
1453: register int rows, top;
1454: char *save [2 * MAX_ROWS];
1455:
1456: if(screen->cursor_state)
1457: HideCursor();
1458: rows = screen->max_row + 1;
1459: bcopy((char *)screen->buf, (char *)save, 2 * sizeof(char *) * rows);
1460: bcopy((char *)screen->altbuf, (char *)screen->buf, 2 * sizeof(char *) *
1461: rows);
1462: bcopy((char *)save, (char *)screen->altbuf, 2 * sizeof(char *) * rows);
1463:
1464: if((top = -screen->topline) <= screen->max_row) {
1465: if(screen->scroll_amt)
1466: FlushScroll(screen);
1467: if(top == 0 && !screen->statusline)
1468: XClear(VWindow(screen));
1469: else
1470: XTileSet(VWindow(screen), screen->border, top *
1471: FontHeight(screen) + screen->border + Titlebar(screen),
1472: Width(screen), (screen->max_row - top + 1) *
1473: FontHeight(screen), screen->bgndtile);
1474: }
1475: ScrnRefresh(screen, 0, 0, rows, screen->max_col + 1);
1476: }
1477:
1478: VTRun()
1479: {
1480: register Screen *screen = &term.screen;
1481: register int i;
1482:
1483: if(!VWindow(screen) && !VTInit()) {
1484: if(TWindow(screen)) {
1485: screen->TekEmu = TRUE;
1486: return;
1487: }
1488: Exit(ERROR_VINIT);
1489: }
1490: screen->cursor_state = OFF;
1491: screen->cursor_set = ON;
1492: if(screen->icon_show) {
1493: if(screen->icon_show < 0) {
1494: screen->icon_show = TRUE;
1495: screen->mappedVwin = &screen->iconVwin;
1496: XMapWindow(screen->iconVwin.window);
1497: }
1498: } else if(!screen->show) {
1499: screen->show = TRUE;
1500: screen->mappedVwin = &screen->fullVwin;
1501: XMapWindow(VWindow(screen));
1502: } else
1503: XRaiseWindow(VWindow(screen));
1504: if(screen->select)
1505: VTSelect();
1506: if (L_flag > 0) {
1507: XWarpMouse (VWindow(screen),
1508: FullWidth(screen) >> 1, FullHeight(screen) >>1);
1509: L_flag = -1;
1510: }
1511: bcnt = 0;
1512: bptr = buffer;
1513: while(Tpushb > Tpushback) {
1514: *bptr++ = *--Tpushb;
1515: bcnt++;
1516: }
1517: bcnt += (i = Tbcnt);
1518: for( ; i > 0 ; i--)
1519: *bptr++ = *Tbptr++;
1520: bptr = buffer;
1521: if(!setjmp(VTend))
1522: VTparse();
1523: HideCursor();
1524: screen->cursor_set = OFF;
1525: VTUnselect();
1526: }
1527:
1528: VTInit()
1529: {
1530: int width, height;
1531: FontInfo *fInfo, *ifInfo;
1532: register Screen *screen = &term.screen;
1533: register Vertex *vp;
1534: register int i, j;
1535: char *def = "=80x24+1+1";
1536: char iconname[128];
1537: static short failed;
1538: Color cdef;
1539: OpaqueFrame twindow;
1540: WindowInfo wininfo;
1541: int x, y;
1542: Window win;
1543: extern char *malloc();
1544:
1545: if(failed)
1546: return(FALSE);
1547:
1548: screen->mappedVwin = &screen->fullVwin;
1549:
1550: TabReset (term.tabs);
1551:
1552: screen->fnt_norm = screen->fnt_bold = screen->fnt_icon = NULL;
1553:
1554: if ((fInfo = XOpenFont(f_n)) == NULL) {
1555: fprintf(stderr, "%s: Could not open font %s!\n",
1556: xterm_name, f_n);
1557: failed = TRUE;
1558: return(FALSE);
1559: }
1560: screen->fnt_norm = fInfo->id;
1561: if (!f_b || !(screen->fnt_bold = XGetFont(f_b))) {
1562: screen->fnt_bold = screen->fnt_norm;
1563: screen->enbolden = TRUE;
1564: }
1565: screen->fullVwin.f_width = fInfo->width;
1566: screen->fullVwin.f_height = fInfo->height;
1567:
1568: if (screen->active_icon) {
1569: if (!screen->fnt_icon) {
1570: if ((ifInfo = XOpenFont(f_i)) == NULL) {
1571: fprintf( stderr, "%s: Could not open font %s!\n",
1572: xterm_name, f_i);
1573: failed = TRUE;
1574: return( FALSE );
1575: }
1576: screen->fnt_icon = ifInfo->id;
1577: } else
1578: XQueryFont( screen->fnt_icon, &ifInfo );
1579:
1580: screen->iconVwin.f_width = ifInfo->width;
1581: screen->iconVwin.f_height = ifInfo->height;
1582: }
1583:
1584: /* X11 arrow cursor feature */
1585: if (curs_shape && strcmp(curs_shape, "arrow") == 0)
1586: screen->curs = make_arrow(screen->mousecolor,
1587: screen->background, GXcopy);
1588: else
1589: screen->curs = make_xterm(screen->mousecolor,
1590: screen->background, GXcopy);
1591:
1592: twindow.bdrwidth = screen->borderwidth;
1593: if(grayborder)
1594: twindow.border = screen->graybordertile;
1595: else
1596: twindow.border = screen->bordertile;
1597: twindow.background = screen->bgndtile;
1598: if((screen->minrows = (MINSCROLLBARHEIGHT - 2 * screen->border +
1599: fInfo->height - 1) / fInfo->height) < 0)
1600: screen->minrows = 0;
1601:
1602: i = 2 * screen->border + screen->scrollbar;
1603: j = 2 * screen->border + Titlebar(screen);
1604: if(screen->statusline)
1605: j += (screen->statusheight = fInfo->height + 2);
1606:
1607: if((screen->fullVwin.window = XCreateTerm ("Terminal Emulator", xterm_name,
1608: geo_metry, def, &twindow, 12, screen->minrows, i, j, &width, &height,
1609: fInfo, fInfo->width, fInfo->height)) == NULL) {
1610: fprintf(stderr, "%s: Can't create VT window\n");
1611: XCloseFont(fInfo);
1612: return(FALSE);
1613: }
1614: XSelectInput(VWindow(screen), WINDOWEVENTS);
1615: /*
1616: * XCreateTerm flushes all events, which might include an EnterWindow
1617: * or LeaveWindow. So if the cursor is not where it is supposed to
1618: * be, we set select to the appropriate thing.
1619: */
1620: if(TWindow(screen) && XQueryMouse(RootWindow, &x, &y, &win)) {
1621: if(screen->timer) {
1622: Timer(0L);
1623: screen->timer = 0;
1624: }
1625: if(win == TWindow(screen))
1626: screen->select |= INWINDOW;
1627: else
1628: screen->select &= ~INWINDOW;
1629: }
1630:
1631: screen->fullVwin.fullwidth = twindow.width;
1632: screen->fullVwin.fullheight = twindow.height;
1633: screen->fullVwin.width = twindow.width - i;
1634: screen->fullVwin.height = twindow.height - j;
1635:
1636: /* Reset variables used by ANSI emulation. */
1637:
1638: screen->gsets[0] = 'B'; /* ASCII_G */
1639: screen->gsets[1] = 'B';
1640: screen->gsets[2] = 'B'; /* DEC supplemental. */
1641: screen->gsets[3] = 'B';
1642: screen->curgl = 0; /* G0 => GL. */
1643: screen->curgr = 2; /* G2 => GR. */
1644: screen->curss = 0; /* No single shift. */
1645:
1646: if(screen->iconTwin.window) {
1647: XQueryWindow(screen->iconTwin.window, &wininfo);
1648: x = wininfo.x;
1649: y = wininfo.y;
1650: } else {
1651: x = twindow.x + (twindow.width - screen->iconVwin.width) / 2;
1652: y = twindow.y + (twindow.height - screen->iconVwin.height) / 2;
1653: IconGeometry(screen, &x, &y);
1654: }
1655: screen->iconVwin.window =
1656: XCreateWindow( RootWindow, x, y, 1, 1, screen->borderwidth,
1657: screen->bordertile, screen->bgndtile );
1658:
1659: XSetIconWindow( screen->fullVwin.window, screen->iconVwin.window );
1660:
1661: XDefineCursor( screen->iconVwin.window, screen->arrow );
1662: XSelectInput( screen->iconVwin.window,
1663: screen->active_icon && (term.flags & ICONINPUT)
1664: ? ICONWINDOWEVENTS | ICONINPUTEVENTS
1665: : ICONWINDOWEVENTS );
1666:
1667: XDefineCursor( VWindow(screen), screen->curs );
1668: XStoreName (VWindow(screen), screen->winname);
1669: strcpy(iconname, screen->winname);
1670: strcat(iconname, " (icon)");
1671: XStoreName (screen->iconVwin.window, iconname);
1672: XSetResizeHint (VWindow(screen), 2 * screen->border + screen->scrollbar,
1673: 2 * screen->border + Titlebar(screen) + screen->statusheight,
1674: fInfo->width, fInfo->height);
1675:
1676: screen->cur_col = screen->cur_row = 0;
1677: screen->max_col = Width(screen) / fInfo->width - 1;
1678: screen->top_marg = 0;
1679: screen->bot_marg = screen->max_row = Height(screen) / fInfo->height - 1;
1680:
1681: screen->sc.row = screen->sc.col = screen->sc.flags = NULL;
1682:
1683: SetIconSize( screen ); /* requires max_col, max_row */
1684:
1685: /* allocate memory for screen buffer (including one for status line */
1686: screen->buf = screen->allbuf = (ScrnBuf) Allocate (screen->max_row + 2,
1687: screen->max_col +1);
1688:
1689: screen->do_wrap = NULL;
1690: screen->scrolls = screen->incopy = 0;
1691: free((char *)fInfo);
1692: vp = &VTbox[1];
1693: (vp++)->x = FontWidth(screen) - 1;
1694: (vp++)->y = FontHeight(screen) - 1;
1695: (vp++)->x = -(FontWidth(screen) - 1);
1696: vp->y = -(FontHeight(screen) - 1);
1697: screen->box = VTbox;
1698: status_box[0].x = screen->border - 1;
1699: screen->savelines = save_lines;
1700: if(screen->scrollbar) {
1701: screen->scrollbar = 0;
1702: ScrollBarOn(screen, TRUE, TRUE);
1703: screen->sb->action = NONE;
1704: }
1705: screen->nmarginbell = n_marginbell;
1706: if(Titlebar(screen))
1707: VTTitleShow(TRUE);
1708: CursorSave(&term, &screen->sc);
1709: return(TRUE);
1710: }
1711:
1712: #ifdef CHANGEFONT
1713: VTChangeFont(screen, newfname)
1714: register Screen *screen;
1715: char *newfname;
1716: {
1717: register Vertex *vp;
1718: FontInfo *fInfo;
1719: register width, height, border, extra;
1720:
1721: /* Make sure we can get the new font */
1722: if ((fInfo = XOpenFont(newfname)) == NULL)
1723: return(FALSE);
1724:
1725: /* Disallow variable fonts with no average sizes for now */
1726: if (fInfo->width == 0 || fInfo->height == 0) {
1727: XCloseFont(fInfo);
1728: return(FALSE);
1729: }
1730:
1731: /* Destroy old font */
1732: XFreeFont(screen->fnt_norm);
1733:
1734: screen->fnt_norm = fInfo->id;
1735:
1736: if (screen->enbolden)
1737: screen->fnt_bold = screen->fnt_norm;
1738:
1739: XSetResizeHint (VWindow(screen), 2 * screen->border + screen->scrollbar,
1740: 2 * screen->border + Titlebar(screen) + screen->statusheight,
1741: fInfo->width, fInfo->height);
1742:
1743: screen->fullVwin.f_width = fInfo->width;
1744: screen->fullVwin.f_height = fInfo->height;
1745:
1746: free((char *)fInfo);
1747:
1748: width = FontWidth(screen) * (screen->max_col + 1);
1749: height = FontHeight(screen) * (screen->max_row + 1);
1750: border = 2 * screen->border;
1751: extra = Titlebar(screen) + screen->statusheight;
1752:
1753: screen->fullVwin.fullwidth = width;
1754: screen->fullVwin.fullheight = height;
1755: screen->fullVwin.height = height - extra;
1756: screen->fullVwin.width = width;
1757:
1758: vp = &VTbox[1];
1759: (vp++)->x = FontWidth(screen) - 1;
1760: (vp++)->y = FontHeight(screen) - 1;
1761: (vp++)->x = -(FontWidth(screen) - 1);
1762: vp->y = -(FontHeight(screen) - 1);
1763:
1764: if(screen->sb)
1765: ResizeScrollBar(screen->sb, width - SCROLLBARWIDTH,
1766: Titlebar(screen) - 1, height - Titlebar(screen),
1767: screen->max_row + 1);
1768: if(screen->title.tbar)
1769: VTTitleResize(width);
1770:
1771: return(TRUE);
1772: }
1773: #endif
1774:
1775: VTExpose(rep)
1776: register XExposeWindowEvent *rep;
1777: {
1778: register Screen *screen = &term.screen;
1779:
1780: if (rep && ScreenResize (screen, rep->width, rep->height, &term.flags)
1781: == -1)
1782: return;
1783: XClear (VWindow(screen));
1784: ScrnRefresh(screen, 0, 0, screen->max_row + 1 + screen->statusline,
1785: screen->max_col + 1);
1786: }
1787:
1788: /*
1789: * Shows cursor at new cursor position in screen.
1790: */
1791: ShowCursor()
1792: {
1793: register Screen *screen = &term.screen;
1794: register int fg;
1795: register int bg;
1796: register int x, y, flags;
1797: register Font fnt;
1798: char c;
1799:
1800: if (screen->icon_show && !screen->active_icon) return;
1801:
1802: if(!screen->instatus && screen->cur_row - screen->topline >
1803: screen->max_row)
1804: return;
1805: c = screen->buf[y = 2 * (screen->cursor_row = screen->cur_row)]
1806: [x = screen->cursor_col = screen->cur_col];
1807: flags = screen->buf[y + 1][x];
1808: if (c == 0)
1809: c = ' ';
1810: if(screen->instatus)
1811: flags ^= INVERSE;
1812: if(screen->select) {
1813: if(flags & INVERSE) {
1814: if(screen->cursorcolor != screen->foreground) {
1815: fg = screen->foreground;
1816: bg = screen->cursorcolor;
1817: } else {
1818: fg = screen->foreground;
1819: bg = screen->background;
1820: }
1821: } else {
1822: fg = screen->background;
1823: bg = screen->cursorcolor;
1824: }
1825: } else {
1826: if(flags & INVERSE) {
1827: fg = screen->background;
1828: bg = screen->foreground;
1829: } else {
1830: fg = screen->foreground;
1831: bg = screen->background;
1832: }
1833: }
1834: fnt = ActiveIcon(screen) ? screen->fnt_icon
1835: : (flags & BOLD) ? screen->fnt_bold : screen->fnt_norm;
1836: XText(VWindow(screen), x = CursorX (screen, screen->cur_col),
1837: y = CursorY(screen, screen->cur_row), &c, 1, fnt, fg, bg);
1838: if((flags & BOLD) && screen->enbolden)
1839: XTextMask(VWindow(screen), x + 1, y, &c, 1, fnt, fg);
1840: if(flags & UNDERLINE) {
1841: bg = y + FontHeight(screen) - 2;
1842: XLine(VWindow(screen), x, bg, x + FontWidth(screen), bg,
1843: 1, 1, fg, GXcopy, AllPlanes);
1844: }
1845: if(!screen->select && !ActiveIcon(screen)) {
1846: screen->box->x = x;
1847: screen->box->y = y;
1848: XDraw(VWindow(screen), screen->box, NBOX, 1, 1, fg, GXcopy,
1849: AllPlanes);
1850: }
1851: screen->cursor_state = ON;
1852: }
1853:
1854: /*
1855: * hide cursor at previous cursor position in screen.
1856: */
1857: HideCursor()
1858: {
1859: register Screen *screen = &term.screen;
1860: register int fg;
1861: register int bg;
1862: register int x, y, flags, instatus;
1863: register Font fnt;
1864: char c;
1865:
1866: if (screen->icon_show && !screen->active_icon) return;
1867:
1868: if(!(instatus = screen->cursor_row > screen->max_row) &&
1869: screen->cursor_row - screen->topline > screen->max_row)
1870: return;
1871: c = screen->buf[y = 2 * screen->cursor_row][x = screen->cursor_col];
1872: flags = screen->buf[y + 1][x];
1873: if(instatus)
1874: flags ^= INVERSE;
1875: if(flags & INVERSE) {
1876: fg = screen->background;
1877: bg = screen->foreground;
1878: } else {
1879: fg = screen->foreground;
1880: bg = screen->background;
1881: }
1882: if (c == 0)
1883: c = ' ';
1884: y = (instatus ? (screen->cursor_row * FontHeight(screen) + 1) :
1885: ((screen->cursor_row - screen->topline) * FontHeight(screen))) +
1886: Titlebar(screen) + screen->border;
1887: fnt = ActiveIcon(screen) ? screen->fnt_icon
1888: : (flags & BOLD) ? screen->fnt_bold : screen->fnt_norm;
1889: XText(VWindow(screen), x = CursorX (screen, screen->cursor_col),
1890: y, &c, 1, fnt, fg, bg);
1891: if((flags & BOLD) && screen->enbolden)
1892: XTextMask(VWindow(screen), x + 1, y, &c, 1, fnt, fg);
1893: if(flags & UNDERLINE) {
1894: y += FontHeight(screen) - 2;
1895: XLine(VWindow(screen), x, y, x + FontWidth(screen), y,
1896: 1, 1, fg, GXcopy, AllPlanes);
1897: }
1898: screen->cursor_state = OFF;
1899: }
1900:
1901: VTSelect()
1902: {
1903: register Screen *screen = &term.screen;
1904:
1905: if(grayborder && screen->borderwidth > 0)
1906: XChangeBorder(VWindow(screen), screen->bordertile);
1907: if(Titlebar(screen))
1908: VTTitleHilite();
1909: }
1910:
1911: VTUnselect()
1912: {
1913: register Screen *screen = &term.screen;
1914:
1915: if(grayborder && screen->borderwidth > 0)
1916: XChangeBorder(VWindow(screen), screen->graybordertile);
1917: if(Titlebar(screen))
1918: VTTitleUnhilite();
1919: }
1920:
1921: VTReset(full)
1922: int full;
1923: {
1924: register Screen *screen = &term.screen;
1925:
1926: /* reset scrolling region */
1927: screen->top_marg = 0;
1928: screen->bot_marg = screen->max_row;
1929: term.flags &= ~ORIGIN;
1930: if(full) {
1931: TabReset (term.tabs);
1932: term.keyboard.flags = NULL;
1933: screen->gsets[0] = 'B';
1934: screen->gsets[1] = 'B';
1935: screen->gsets[2] = 'B';
1936: screen->gsets[3] = 'B';
1937: screen->curgl = 0;
1938: screen->curgr = 2;
1939: screen->curss = 0;
1940: ClearScreen(screen);
1941: screen->cursor_state = OFF;
1942: if(!(term.flags & AUTOREPEAT))
1943: XAutoRepeatOn();
1944: if (term.flags & REVERSE_VIDEO)
1945: ReverseVideo(&term);
1946:
1947: term.flags = term.initflags;
1948: if(screen->c132 && (term.flags & IN132COLUMNS)) {
1949: XChangeWindow (VWindow(screen), 80 * FontWidth(screen) +
1950: 2 * screen->border + screen->scrollbar,
1951: FontHeight(screen) * (screen->max_row + 1) +
1952: screen->statusheight + Titlebar(screen) +
1953: 2 * screen->border);
1954: XSync(FALSE); /* synchronize */
1955: if(QLength() > 0)
1956: xevents();
1957: }
1958: CursorSet(screen, 0, 0, term.flags);
1959: }
1960: longjmp(vtjmpbuf, 1); /* force ground state in parser */
1961: }
1962:
1963: ToStatus(col)
1964: int col;
1965: {
1966: register Screen *screen = &term.screen;
1967:
1968: if(col > screen->max_col)
1969: col = screen->max_col;
1970: if(!screen->instatus) {
1971: if(!screen->statusline)
1972: ShowStatus();
1973: CursorSave(&term, &screen->statussc);
1974: screen->instatus = TRUE;
1975: screen->cur_row = screen->max_row + 1;
1976: }
1977: screen->cur_col = col;
1978: }
1979:
1980: FromStatus()
1981: {
1982: register Screen *screen = &term.screen;
1983:
1984: if(!screen->instatus)
1985: return;
1986: screen->instatus = FALSE;
1987: CursorRestore(&term, &screen->statussc);
1988: }
1989:
1990: ShowStatus()
1991: {
1992: register Screen *screen = &term.screen;
1993: register int border = 2 * screen->border;
1994:
1995: if(screen->statusline)
1996: return;
1997: screen->statusline = 1;
1998: screen->statusheight = FontHeight(screen) + 2;
1999: XSetResizeHint(VWindow(screen), border + screen->scrollbar, border +
2000: Titlebar(screen) + screen->statusheight, FontWidth(screen),
2001: FontHeight(screen));
2002: XChangeWindow (VWindow(screen), FontWidth(screen) * (screen->max_col + 1)
2003: + border + screen->scrollbar, FontHeight(screen) *
2004: (screen->max_row + 1) + screen->statusheight + Titlebar(screen) +
2005: border);
2006: }
2007:
2008: HideStatus()
2009: {
2010: register Screen *screen = &term.screen;
2011: register int border = 2 * screen->border;
2012: register int i, j;
2013:
2014: if(!screen->statusline)
2015: return;
2016: if(screen->instatus)
2017: FromStatus();
2018: screen->statusline = 0;
2019: screen->statusheight = 0;
2020: bzero(screen->buf[i = 2 * (screen->max_row + 1)], j = screen->max_col +
2021: 1);
2022: bzero(screen->buf[i + 1], j);
2023: XSetResizeHint(VWindow(screen), border + screen->scrollbar, border +
2024: Titlebar(screen), FontWidth(screen), FontHeight(screen));
2025: XChangeWindow (VWindow(screen), FontWidth(screen) * j + border +
2026: screen->scrollbar, FontHeight(screen) * (screen->max_row + 1) +
2027: border + Titlebar(screen));
2028: }
2029:
2030: EraseStatus()
2031: {
2032: register Screen *screen = &term.screen;
2033: register int i, j, pix;
2034:
2035: if(!screen->statusline)
2036: return;
2037: bzero(screen->buf[i = 2 * (screen->max_row + 1)], j = screen->max_col +
2038: 1);
2039: bzero(screen->buf[i + 1], j);
2040: XPixSet(VWindow(screen), screen->border - 1, (screen->max_row + 1) *
2041: FontHeight(screen) + screen->border + Titlebar(screen), j *
2042: FontWidth(screen) + 2, screen->statusheight, screen->reversestatus ?
2043: screen->foreground : screen->background);
2044: if(!screen->reversestatus)
2045: StatusBox(screen);
2046: }
2047:
2048: StatusBox(screen)
2049: register Screen *screen;
2050: {
2051: status_box[0].y = (screen->max_row + 1) * FontHeight(screen) +
2052: screen->border + Titlebar(screen);
2053: status_box[3].x = -(status_box[1].x = (screen->max_col + 1) *
2054: FontWidth(screen) + 1);
2055: status_box[4].y = -(status_box[2].y = FontHeight(screen) + 1);
2056: XDraw(VWindow(screen), status_box, NBOX, 1, 1, screen->foreground,
2057: GXcopy, AllPlanes);
2058: }
2059:
2060: VTTitleShow(init)
2061: int init;
2062: {
2063: register Screen *screen = &term.screen;
2064: register int border = 2 * screen->border;
2065:
2066: if(!screen->title.tbar)
2067: VTTitleInit();
2068: if(!init) {
2069: XSetResizeHint(VWindow(screen), border + screen->scrollbar,
2070: border + Titlebar(screen) + screen->statusheight,
2071: FontWidth(screen), FontHeight(screen));
2072: XChangeWindow (VWindow(screen), FontWidth(screen) *
2073: (screen->max_col + 1) + border + screen->scrollbar,
2074: FontHeight(screen) * (screen->max_row + 1) + screen->statusheight
2075: + Titlebar(screen) + border);
2076: }
2077: if(screen->select && !screen->TekEmu)
2078: VTTitleHilite();
2079: else
2080: VTTitleUnhilite();
2081: XMapWindow(screen->title.tbar);
2082: }
2083:
2084: VTTitleHide()
2085: {
2086: register Screen *screen = &term.screen;
2087: register int border = 2 * screen->border;
2088:
2089: XUnmapWindow(screen->title.tbar);
2090: XSetResizeHint(VWindow(screen), border + screen->scrollbar, border +
2091: screen->statusheight, FontWidth(screen), FontHeight(screen));
2092: XChangeWindow (VWindow(screen), FontWidth(screen) * (screen->max_col + 1)
2093: + border + screen->scrollbar, FontHeight(screen) *
2094: (screen->max_row + 1) + screen->statusheight + border);
2095: }
2096:
2097: VTTitleHilite()
2098: {
2099: register Screen *screen = &term.screen;
2100:
2101: if(screen->title.hilited)
2102: return;
2103: XMapWindow(screen->title.left);
2104: XMapWindow(screen->title.right);
2105: screen->title.hilited = TRUE;
2106: }
2107:
2108: VTTitleUnhilite()
2109: {
2110: register Screen *screen = &term.screen;
2111:
2112: if(!screen->title.hilited)
2113: return;
2114: XUnmapWindow(screen->title.left);
2115: XUnmapWindow(screen->title.right);
2116: screen->title.hilited = FALSE;
2117: }
2118:
2119: VTTitleResize(width)
2120: register int width;
2121: {
2122: register Screen *screen = &term.screen;
2123: register int i, j;
2124:
2125: if((screen->title.width = i = screen->title.fullwidth) >
2126: (j = width - 2 * (MINHILITE + screen->title_n_size + 1)))
2127: screen->title.width = (i = j) + screen->title_n_size;
2128: j = width - i - 2 * (screen->title_n_size + 1);
2129: i = j / 2;
2130: j -= i;
2131: screen->title.x = i + 1 + screen->title_n_size;
2132: XChangeWindow(screen->title.tbar, width, screen->titleheight - 1);
2133: XChangeWindow(screen->title.left, i, screen->titlefont->height);
2134: XConfigureWindow(screen->title.right, width - j - 1, TITLEPAD, j,
2135: screen->titlefont->height);
2136: }
2137:
2138: VTTitleExpose(rep)
2139: register XExposeWindowEvent *rep;
2140: {
2141: register Screen *screen = &term.screen;
2142:
2143: if(rep && (rep->x > (screen->title.x + screen->title.width) ||
2144: (rep->x + rep->width) < screen->title.x ||
2145: rep->y > (screen->title.y + screen->titlefont->height) ||
2146: (rep->y + rep->height) < screen->title.y))
2147: return;
2148: XText(screen->title.tbar, screen->title.x, screen->title.y,
2149: screen->winname, screen->winnamelen, screen->titlefont->id,
2150: screen->foreground, screen->background);
2151: }
2152:
2153: VTTitleInit()
2154: {
2155: register Screen *screen = &term.screen;
2156: register int w, i, j;
2157: OpaqueFrame hilite[2];
2158: extern Pixmap make_hilite();
2159:
2160: if((screen->title.tbar = XCreateWindow(VWindow(screen), -1, -1,
2161: w = FullWidth(screen), screen->titleheight - 1, 1, screen->bordertile,
2162: screen->bgndtile)) == NULL)
2163: Error(ERROR_CRTITLE);
2164: XSelectInput(screen->title.tbar, ButtonPressed | ButtonReleased |
2165: ExposeWindow | EnterWindow | LeaveWindow | UnmapWindow);
2166: XDefineCursor(screen->title.tbar, screen->arrow);
2167: if(!screen->hilitetile && (screen->hilitetile =
2168: make_hilite(screen->foreground, screen->background)) == NULL)
2169: Error(ERROR_HILITE);
2170: screen->title.fullwidth = XQueryWidth(screen->winname,
2171: screen->titlefont->id);
2172: if((screen->title.width = i = screen->title.fullwidth) >
2173: (j = w - 2 * (MINHILITE + screen->title_n_size + 1)))
2174: screen->title.width = (i = j) + screen->title_n_size;
2175: j = w - i - 2 * (screen->title_n_size + 1);
2176: i = j / 2;
2177: j -= i;
2178: screen->title.x = i + 1 + screen->title_n_size;
2179: screen->title.y = TITLEPAD;
2180: hilite[0].x = 1;
2181: hilite[1].x = w - j - 1;
2182: hilite[0].y = hilite[1].y = TITLEPAD;
2183: hilite[0].width = i;
2184: hilite[1].width = j;
2185: hilite[0].height = hilite[1].height = screen->titlefont->height;
2186: hilite[0].bdrwidth = hilite[1].bdrwidth = 0;
2187: hilite[0].border = hilite[1].border = NULL;
2188: hilite[0].background = hilite[1].background = screen->hilitetile;
2189: if(XCreateWindows(screen->title.tbar, hilite, 2) != 2)
2190: Error(ERROR_CRLFRG);
2191: screen->title.left = hilite[0].self;
2192: screen->title.right = hilite[1].self;
2193: }
2194:
2195: #ifdef MODEMENU
2196: #define MMENU_SCROLL 0
2197: #define MMENU_VIDEO (MMENU_SCROLL+1)
2198: #define MMENU_WRAP (MMENU_VIDEO+1)
2199: #define MMENU_REVERSEWRAP (MMENU_WRAP+1)
2200: #define MMENU_NLM (MMENU_REVERSEWRAP+1)
2201: #define MMENU_CURSOR (MMENU_NLM+1)
2202: #define MMENU_PAD (MMENU_CURSOR+1)
2203: #define MMENU_REPEAT (MMENU_PAD+1)
2204: #define MMENU_SCROLLBAR (MMENU_REPEAT+1)
2205: #define MMENU_PAGEMODE (MMENU_SCROLLBAR+1)
2206: #define MMENU_STATUS (MMENU_PAGEMODE+1)
2207: #define MMENU_REVSTATUS (MMENU_STATUS+1)
2208: #define MMENU_C132 (MMENU_REVSTATUS+1)
2209: #define MMENU_CURSES (MMENU_C132+1)
2210: #define MMENU_MARGBELL (MMENU_CURSES+1)
2211: #define MMENU_TEKWIN (MMENU_MARGBELL+1)
2212: #define MMENU_ALTERN (MMENU_TEKWIN+1)
2213: #define MMENU_LINE (MMENU_ALTERN+1)
2214: #define MMENU_RESET (MMENU_LINE+1)
2215: #define MMENU_FULLRESET (MMENU_RESET+1)
2216: #define MMENU_TEKMODE (MMENU_FULLRESET+1)
2217: #define MMENU_HIDEVT (MMENU_TEKMODE+1)
2218:
2219: static char *vtext[] = {
2220: "Jump Scroll",
2221: "Reverse Video",
2222: "Auto Wraparound",
2223: "Reverse Wraparound",
2224: "Auto Linefeed",
2225: "Application Cursors",
2226: "Application Pad",
2227: "Auto Repeat",
2228: "Scrollbar",
2229: "Page Scroll",
2230: "Status Line",
2231: "Reverse Status Line",
2232: "80 <-> 132 Columns",
2233: "Curses Emulation",
2234: "Margin Bell",
2235: "Tek Window Showing",
2236: "Alternate Screen",
2237: "-",
2238: "Soft Reset",
2239: "Full Reset",
2240: "Select Tek Mode",
2241: "Hide VT Window",
2242: 0,
2243: };
2244:
2245:
2246: static int menutermflags;
2247: static int menukbdflags;
2248: static int t132;
2249: static int taltern;
2250: static int tcurses;
2251: static int tmarginbell;
2252: static int tpagemode;
2253: static int trevstatus;
2254: static int tscrollbar;
2255: static int tshow;
2256: static int tstatusline;
2257:
2258: Menu *setupmenu(menu)
2259: register Menu **menu;
2260: {
2261: register Screen *screen = &term.screen;
2262: register char **cp;
2263: register int flags = term.flags;
2264: register int kflags = term.keyboard.flags;
2265:
2266: if (*menu == NULL) {
2267: if ((*menu = NewMenu("Modes", re_verse)) == NULL)
2268: return(NULL);
2269: for(cp = vtext ; *cp ; cp++)
2270: AddMenuItem(*menu, *cp);
2271: if(!(flags & SMOOTHSCROLL))
2272: CheckItem(*menu, MMENU_SCROLL);
2273: if(flags & REVERSE_VIDEO)
2274: CheckItem(*menu, MMENU_VIDEO);
2275: if(flags & WRAPAROUND)
2276: CheckItem(*menu, MMENU_WRAP);
2277: if(flags & REVERSEWRAP)
2278: CheckItem(*menu, MMENU_REVERSEWRAP);
2279: if(flags & LINEFEED)
2280: CheckItem(*menu, MMENU_NLM);
2281: if(kflags & CURSOR_APL)
2282: CheckItem(*menu, MMENU_CURSOR);
2283: if(kflags & KYPD_APL)
2284: CheckItem(*menu, MMENU_PAD);
2285: if(flags & AUTOREPEAT)
2286: CheckItem(*menu, MMENU_REPEAT);
2287: if(tscrollbar = (screen->scrollbar > 0))
2288: CheckItem(*menu, MMENU_SCROLLBAR);
2289: if(tpagemode = screen->pagemode)
2290: CheckItem(*menu, MMENU_PAGEMODE);
2291: if(tstatusline = screen->statusline)
2292: CheckItem(*menu, MMENU_STATUS);
2293: if(trevstatus = screen->reversestatus)
2294: CheckItem(*menu, MMENU_REVSTATUS);
2295: if(t132 = screen->c132)
2296: CheckItem(*menu, MMENU_C132);
2297: if(tcurses = screen->curses)
2298: CheckItem(*menu, MMENU_CURSES);
2299: if(tmarginbell = screen->marginbell)
2300: CheckItem(*menu, MMENU_MARGBELL);
2301: if(tshow = screen->Tshow)
2302: CheckItem(*menu, MMENU_TEKWIN);
2303: else
2304: DisableItem(*menu, MMENU_HIDEVT);
2305: DisableItem(*menu, MMENU_ALTERN);
2306: if(taltern = screen->alternate) {
2307: CheckItem(*menu, MMENU_ALTERN);
2308: DisableItem(*menu, MMENU_PAGEMODE);
2309: }
2310: DisableItem(*menu, MMENU_LINE);
2311: if(screen->inhibit & I_TEK) {
2312: DisableItem(*menu, MMENU_TEKWIN);
2313: DisableItem(*menu, MMENU_TEKMODE);
2314: }
2315: menutermflags = flags;
2316: menukbdflags = kflags;
2317: return(*menu);
2318: }
2319: if ((menutermflags ^= flags) & SMOOTHSCROLL)
2320: SetItemCheck(*menu, MMENU_SCROLL, !(flags & SMOOTHSCROLL));
2321: if (menutermflags & REVERSE_VIDEO)
2322: SetItemCheck(*menu, MMENU_VIDEO, flags & REVERSE_VIDEO);
2323: if (menutermflags & WRAPAROUND)
2324: SetItemCheck(*menu, MMENU_WRAP, flags & WRAPAROUND);
2325: if (menutermflags & REVERSEWRAP)
2326: SetItemCheck(*menu, MMENU_REVERSEWRAP, flags & REVERSEWRAP);
2327: if (menutermflags & LINEFEED)
2328: SetItemCheck(*menu, MMENU_NLM, flags & LINEFEED);
2329: if ((menukbdflags ^= kflags) & CURSOR_APL)
2330: SetItemCheck(*menu, MMENU_CURSOR, kflags & CURSOR_APL);
2331: if (menukbdflags & KYPD_APL)
2332: SetItemCheck(*menu, MMENU_PAD, NULL, kflags & KYPD_APL);
2333: if(tscrollbar != (screen->scrollbar > 0))
2334: SetItemCheck(*menu, MMENU_SCROLLBAR, (tscrollbar =
2335: (screen->scrollbar > 0)));
2336: if(tpagemode != screen->pagemode)
2337: SetItemCheck(*menu, MMENU_PAGEMODE, (tpagemode =
2338: screen->pagemode));
2339: if(tstatusline != screen->statusline)
2340: SetItemCheck(*menu, MMENU_STATUS, (tstatusline =
2341: screen->statusline));
2342: if(trevstatus != screen->reversestatus)
2343: SetItemCheck(*menu, MMENU_REVSTATUS, (trevstatus =
2344: screen->reversestatus));
2345: if(t132 != screen->c132)
2346: SetItemCheck(*menu, MMENU_C132, (t132 = screen->c132));
2347: if(tcurses != screen->curses)
2348: SetItemCheck(*menu, MMENU_CURSES, (tcurses = screen->curses));
2349: if(tmarginbell != screen->marginbell)
2350: SetItemCheck(*menu, MMENU_MARGBELL, (tmarginbell =
2351: screen->marginbell));
2352: if(tshow != screen->Tshow) {
2353: SetItemCheck(*menu, MMENU_TEKWIN, (tshow = screen->Tshow));
2354: SetItemDisable(*menu, MMENU_HIDEVT, !tshow);
2355: }
2356: if(taltern != screen->alternate) {
2357: SetItemCheck(*menu, MMENU_ALTERN, (taltern =
2358: screen->alternate));
2359: SetItemDisable(*menu, MMENU_PAGEMODE, taltern);
2360: }
2361: menutermflags = flags;
2362: menukbdflags = kflags;
2363: return(*menu);
2364: }
2365:
2366: domenufunc(item)
2367: int item;
2368: {
2369: register Screen *screen = &term.screen;
2370:
2371: switch (item) {
2372: case MMENU_SCROLL:
2373: term.flags ^= SMOOTHSCROLL;
2374: if (term.flags & SMOOTHSCROLL) {
2375: screen->jumpscroll = FALSE;
2376: if (screen->scroll_amt)
2377: FlushScroll(screen);
2378: } else
2379: screen->jumpscroll = TRUE;
2380: break;
2381:
2382: case MMENU_VIDEO:
2383: term.flags ^= REVERSE_VIDEO;
2384: ReverseVideo(&term);
2385: break;
2386:
2387: case MMENU_WRAP:
2388: term.flags ^= WRAPAROUND;
2389: break;
2390:
2391: case MMENU_REVERSEWRAP:
2392: term.flags ^= REVERSEWRAP;
2393: break;
2394:
2395: case MMENU_NLM:
2396: term.flags ^= LINEFEED;
2397: break;
2398:
2399: case MMENU_CURSOR:
2400: term.keyboard.flags ^= CURSOR_APL;
2401: break;
2402:
2403: case MMENU_PAD:
2404: term.keyboard.flags ^= KYPD_APL;
2405: break;
2406:
2407: case MMENU_REPEAT:
2408: term.flags ^= AUTOREPEAT;
2409: if (term.flags & AUTOREPEAT)
2410: XAutoRepeatOn();
2411: else
2412: XAutoRepeatOff();
2413: break;
2414:
2415: case MMENU_SCROLLBAR:
2416: if(screen->scrollbar)
2417: ScrollBarOff(screen);
2418: else
2419: ScrollBarOn(screen, TRUE, FALSE);
2420: break;
2421:
2422: case MMENU_PAGEMODE:
2423: if(screen->pagemode = !screen->pagemode)
2424: screen->pagecnt = 0;
2425: break;
2426:
2427: case MMENU_STATUS:
2428: if(screen->statusline)
2429: HideStatus();
2430: else
2431: ShowStatus();
2432: break;
2433:
2434: case MMENU_REVSTATUS:
2435: screen->reversestatus = !screen->reversestatus;
2436: ScrnRefresh(screen, screen->max_row + 1, 0, 1, screen->max_col
2437: + 1);
2438: break;
2439:
2440: case MMENU_C132:
2441: screen->c132 = !screen->c132;
2442: break;
2443:
2444: case MMENU_MARGBELL:
2445: if(!(screen->marginbell = !screen->marginbell))
2446: screen->bellarmed = -1;
2447: break;
2448:
2449: case MMENU_CURSES:
2450: screen->curses = !screen->curses;
2451: break;
2452:
2453: case MMENU_FULLRESET:
2454: VTReset(TRUE);
2455: break;
2456:
2457: case MMENU_RESET:
2458: VTReset(FALSE);
2459: break;
2460:
2461: case MMENU_HIDEVT:
2462: screen->show = FALSE;
2463: XUnmapWindow(VWindow(screen));
2464: reselectwindow(screen);
2465: SyncUnmap(VWindow(screen), WINDOWEVENTS);
2466: /* drop through */
2467: case MMENU_TEKMODE:
2468: if(!screen->TekEmu) {
2469: if(screen->logging) {
2470: FlushLog(screen);
2471: screen->logstart = Tbuffer;
2472: }
2473: screen->TekEmu = TRUE;
2474: if(screen->pagemode) {
2475: Scroll(screen, screen->pagecnt);
2476: screen->pagecnt = 0;
2477: ioctl(screen->respond, TIOCSTART, NULL);
2478: }
2479: longjmp(VTend, 1);
2480: } else
2481: XRaiseWindow(TWindow(screen));
2482: break;
2483:
2484: case MMENU_TEKWIN:
2485: if(screen->Tshow = !screen->Tshow) {
2486: if(TWindow(screen) || TekInit()) {
2487: XMapWindow(TWindow(screen));
2488: screen->Tshow = TRUE;
2489: }
2490: } else {
2491: screen->Tshow = FALSE;
2492: XUnmapWindow(TWindow(screen));
2493: SyncUnmap(TWindow(screen), TWINDOWEVENTS);
2494: if(screen->TekEmu) {
2495: if(screen->logging) {
2496: FlushLog(screen);
2497: screen->logstart = buffer;
2498: }
2499: longjmp(Tekend, 1);
2500: }
2501: }
2502: reselectwindow(screen);
2503: break;
2504: }
2505: }
2506: #endif MODEMENU
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.