Annotation of freem/src/service.c, revision 1.3
1.1 snw 1: /*
2: * *
3: * * *
4: * * *
5: * ***************
6: * * * * *
7: * * MUMPS *
8: * * * * *
9: * ***************
10: * * *
11: * * *
12: * *
13: *
14: * service.c
15: * terminal and sequential I/O handling,
16: * file and global locking
17: *
18: *
19: * Author: Serena Willis <jpw@coherent-logic.com>
20: * Copyright (C) 1998 MUG Deutschland
21: * Copyright (C) 2020 Coherent Logic Development LLC
22: *
23: *
24: * This file is part of FreeM.
25: *
26: * FreeM is free software: you can redistribute it and/or modify
27: * it under the terms of the GNU Affero Public License as published by
28: * the Free Software Foundation, either version 3 of the License, or
29: * (at your option) any later version.
30: *
31: * FreeM is distributed in the hope that it will be useful,
32: * but WITHOUT ANY WARRANTY; without even the implied warranty of
33: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34: * GNU Affero Public License for more details.
35: *
36: * You should have received a copy of the GNU Affero Public License
37: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
38: *
39: **/
40:
41: #include <errno.h>
42: #include <sys/types.h>
43:
44: #if !defined(__OpenBSD__) && !defined(__FreeBSD__)
45: # include <sys/timeb.h>
46: #endif
47:
48: #include <sys/ioctl.h>
49: #include <unistd.h>
50: #include <stdlib.h>
51:
52: #ifdef AMIGA68K
53: #include <sys/fcntl.h>
54: #endif
55:
56: #define MAXZAS NESTLEVLS
57: #include "mpsdef.h"
58:
59: #include <time.h>
60:
61: #ifdef USE_SYS_TIME_H
62: #include <sys/time.h>
63: #endif
64:
65: #include "events.h"
66:
67: long int tell ();
68: unsigned alarm ();
69: void ris ();
70:
71:
72: #ifdef SCO
73: int scosgr (short att, short bwflag);
74: #endif
75:
76: /* system services */
1.3 ! snw 77: #if !defined(__APPLE__) && !defined(__gnu_hurd__) && !defined(EMSCRIPTEN)
! 78: # if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__AMIGA)
! 79: # include <termios.h>
! 80: # if !defined(__AMIGA)
! 81: # define TCGETA TIOCGETA
! 82: # define TCSETA TIOCSETA
! 83: # endif
! 84: # define termio termios
! 85: # else
! 86: # if !defined(MSDOS)
! 87: # include <termio.h>
! 88: # endif
! 89: # endif
1.2 snw 90: #else
91: # include <termios.h>
92: #endif
1.3 ! snw 93:
1.1 snw 94: #include <fcntl.h>
95:
96: /* search 'string' for occurence of 'pattrn'
97: * return: 0='not found' nbr='pattern begins at nbr' */
98: long int find (char *string, char *pattrn)
99: {
100: short i;
101: short j;
102: register int k;
103: register int l;
104:
105: i = 0;
106:
107: while (pattrn[i] != EOL) i++; /* $l of 2nd arg */
108:
109: if (i == 1) {
110:
111: l = pattrn[0];
112: k = 0;
113:
114: while (string[k] != EOL) {
115:
116: if (string[k++] == l) return k;
117:
118: }
119:
120: return 0L;
121:
122: }
123:
124: j = stlen (string);
125:
126: for (k = 0; k < j; k++) {
127:
128: l = 0;
129:
130:
131: l10:
132:
133: if (string[k + l] != pattrn[l]) continue;
134: if (++l < i) goto l10;
135:
136: return ++k;
137:
138: }
139:
140: return 0L;
141: } /* end of find() */
142:
143: /* called by exclusive KILL to search 'exceptions' for occurence of 'variable'
144: * return: 1='not found, can be killed' 0='cannot be killed' */
145: short int kill_ok (char *exceptions, char *variable)
146: {
147: short i;
148: short j;
149: register int k;
150: register int l;
151:
152: j = stlen (exceptions);
153: i = stlen (variable);
154:
155: for (k = 0; k < j; k++) {
156:
157: for (l = 0; l < i; l++) {
158:
159: if (exceptions[k + l] != variable[l]) {
160:
161: if (exceptions[k + l] == SP && variable[l] == DELIM) return FALSE;
162:
163: goto outerspace;
164:
165: }
166:
167: }
168:
169: return FALSE;
170:
171:
172: outerspace:; /* the semicolon apparently needs to be here in this case. */
173: /* break time. */
174:
175: }
176:
177: return TRUE;
178: } /* end of kill_ok */
179:
180: /* write this format */
181: void write_f (char *intext)
182: {
183: char outtext[256]; /* output string */
184: short l;
185: int i;
186: char final;
187: int csi;
188:
189: csi = FALSE;
190: l = stlen (intext);
191:
192: if (l < 2) return; /* not recognized */
193:
194: for (i = 0; i < l; i++) {
195:
196: if (intext[i] == DELIM) break;
197:
198: }
199:
200:
201: intext[i] = EOL;
202:
203: /* CUB - Cursor Backward */
204: if (!stcmp (intext, "CUB\201")) {
205:
206: csi = TRUE;
207: final = 'D';
208:
209: goto end;
210:
211: }
212:
213: /* CUD - Cursor Down */
214: if (!stcmp (intext, "CUD\201")) {
215:
216: csi = TRUE;
217: final = 'B';
218:
219: goto end;
220:
221: }
222:
223: /* CUF - Cursor Forward */
224: if (!stcmp (intext, "CUF\201")) {
225:
226: csi = TRUE;
227: final = 'C';
228:
229: goto end;
230:
231: }
232:
233: /* CUP - Cursor Position */
234: /* HVP - Horizontal and vertical Position */
235: if (!stcmp (intext, "CUP\201") || !stcmp (intext, "HVP\201")) {
236:
237: csi = TRUE;
238: final = 'H';
239:
240: goto end;
241:
242: }
243:
244: /* CUU - Cursor Up */
245: if (!stcmp (intext, "CUU\201")) {
246:
247: csi = TRUE;
248: final = 'A';
249:
250: goto end;
251:
252: }
253:
254: /* DCH - Delete Character */
255: if (!stcmp (intext, "DCH\201")) {
256:
257: csi = TRUE;
258: final = 'P';
259:
260: goto end;
261:
262: }
263:
264: /* ICH - Insert Character */
265: if (!stcmp (intext, "ICH\201")) {
266:
267: csi = TRUE;
268: final = '@';
269:
270: goto end;
271:
272: }
273:
274: /* DL - Delete Line */
275: if (!stcmp (intext, "DL\201")) {
276:
277: csi = TRUE;
278: final = 'M';
279:
280: goto end;
281:
282: }
283:
284: /* IL - Insert Line */
285: if (!stcmp (intext, "IL\201")) {
286:
287: csi = TRUE;
288: final = 'L';
289:
290: goto end;
291:
292: }
293:
294: /* SU - Scroll Up = pan down */
295: if (!stcmp (intext, "SU\201")) {
296:
297: csi = TRUE;
298: final = 'S';
299:
300: goto end;
301:
302: }
303:
304: /* SD - Scroll Down = pan up */
305: if (!stcmp (intext, "SD\201")) {
306:
307: csi = TRUE;
308: final = 'T';
309:
310: goto end;
311:
312: }
313:
314: /* DA - Device Attributes */
315: if (!stcmp (intext, "DA\201")) {
316:
317: csi = TRUE;
318: final = 'c';
319:
320: goto end;
321:
322: }
323:
324: /* DSR - Device Status Report */
325: if (!stcmp (intext, "DSR\201")) {
326:
327: csi = TRUE;
328: final = 'n';
329:
330: goto end;
331:
332: }
333:
334: /* ED - Erase Display */
335: if (!stcmp (intext, "ED\201")) {
336:
337: csi = TRUE;
338: final = 'J';
339:
340: goto end;
341:
342: }
343:
344: /* EL - Erase Line */
345: if (!stcmp (intext, "EL\201")) {
346:
347: csi = TRUE;
348: final = 'K';
349:
350: goto end;
351:
352: }
353:
354: /* ECH - Erase Character */
355: if (!stcmp (intext, "ECH\201")) {
356:
357: csi = TRUE;
358: final = 'X';
359:
360: goto end;
361:
362: }
363:
364: /* HTS - Horizontal Tabulation Set */
365: if (!stcmp (intext, "HTS\201")) {
366:
367: final = 'H';
368:
369: goto end;
370:
371: }
372:
373: /* IND - Index */
374: if (!stcmp (intext, "IND\201")) {
375:
376: final = 'D';
377:
378: goto end;
379:
380: }
381:
382: /* NEL - NExt Line */
383: if (!stcmp (intext, "NEL\201")) {
384:
385: final = 'E';
386:
387: goto end;
388:
389: }
390:
391: if (!stcmp (intext, "SSA\201")) {
392:
393: final = 'F';
394:
395: goto end;
396:
397: }
398:
399: if (!stcmp (intext, "ESA\201")) {
400:
401: final = 'G';
402:
403: goto end;
404:
405: }
406:
407: if (!stcmp (intext, "HTJ\201")) {
408:
409: final = 'I';
410:
411: goto end;
412:
413: }
414:
415: if (!stcmp (intext, "VTS\201")) {
416:
417: final = 'J';
418:
419: goto end;
420:
421: }
422:
423: if (!stcmp (intext, "PLD\201")) {
424:
425: final = 'K';
426:
427: goto end;
428:
429: }
430:
431: if (!stcmp (intext, "PLU\201")) {
432:
433: final = 'L';
434:
435: goto end;
436:
437: }
438:
439: /* RI - Reverse Index */
440: if (!stcmp (intext, "RI\201")) {
441:
442: final = 'M';
443:
444: goto end;
445:
446: }
447:
448: /* SS2 - Single Shift G2 */
449: if (!stcmp (intext, "SS2\201")) {
450:
451: final = 'N';
452:
453: goto end;
454:
455: }
456:
457: /* SS3 - Single Shift G3 */
458: if (!stcmp (intext, "SS3\201")) {
459:
460: final = 'O';
461:
462: goto end;
463:
464: }
465:
466: /* DCS - Device Control String introducer */
467: if (!stcmp (intext, "DCS\201")) {
468:
469: final = 'P';
470:
471: goto end;
472:
473: }
474:
475: if (!stcmp (intext, "PU1\201")) {
476:
477: final = 'Q';
478:
479: goto end;
480:
481: }
482:
483: if (!stcmp (intext, "PU2\201")) {
484:
485: final = 'R';
486:
487: goto end;
488:
489: }
490:
491: if (!stcmp (intext, "STS\201")) {
492:
493: final = 'S';
494:
495: goto end;
496:
497: }
498:
499: if (!stcmp (intext, "CCH\201")) {
500:
501: final = 'T';
502:
503: goto end;
504:
505: }
506:
507: if (!stcmp (intext, "MW\201")) {
508:
509: final = 'U';
510:
511: goto end;
512:
513: }
514:
515: if (!stcmp (intext, "SPA\201")) {
516:
517: final = 'V';
518:
519: goto end;
520:
521: }
522:
523: if (!stcmp (intext, "EPA\201")) {
524:
525: final = 'W';
526:
527: goto end;
528:
529: }
530:
531: /* CSI - Command String Introducer */
532: if (!stcmp (intext, "CSI\201")) {
533:
534: final = '[';
535:
536: goto end;
537:
538: }
539:
540: /* ST - device control String Terminator */
541: if (!stcmp (intext, "ST\201")) {
542:
543: final = '\\';
544:
545: goto end;
546:
547: }
548:
549: if (!stcmp (intext, "OSC\201")) {
550:
551: final = ']';
552:
553: goto end;
554:
555: }
556:
557: if (!stcmp (intext, "PM\201")) {
558:
559: final = '^';
560:
561: goto end;
562:
563: }
564:
565: if (!stcmp (intext, "APC\201")) {
566:
567: final = '_';
568:
569: goto end;
570:
571: }
572:
573: /* RIS - Reset to Initial State */
574: if (!stcmp (intext, "RIS\201")) {
575:
576: final = 'c';
577:
578: goto end;
579:
580: }
581:
582: /* RM - Reset Mode */
583: if (!stcmp (intext, "RM\201")) {
584:
585: csi = TRUE;
586: final = 'l';
587:
588: goto end;
589:
590: }
591:
592: /* SGR - Select Graphic Rendition */
593: if (!stcmp (intext, "SGR\201")) {
594:
595: csi = TRUE;
596: final = 'm';
597:
598: goto end;
599:
600: }
601:
602: /* SM - Set Mode */
603: if (!stcmp (intext, "SM\201")) {
604:
605: csi = TRUE;
606: final = 'h';
607:
608: goto end;
609:
610: }
611:
612: /* TBC - Tabulation Clear */
613: if (!stcmp (intext, "TBC\201")) {
614:
615: csi = TRUE;
616: final = 'g';
617:
618: goto end;
619:
620: }
621:
622: if (!stcmp (intext, "NUL\201")) {
623:
624: final = NUL;
625:
626: goto controls;
627:
628: }
629:
630: if (!stcmp (intext, "SOH\201")) {
631:
632: final = SOH;
633:
634: goto controls;
635:
636: }
637:
638: if (!stcmp (intext, "STX\201")) {
639:
640: final = STX;
641:
642: goto controls;
643:
644: }
645:
646: if (!stcmp (intext, "ETX\201")) {
647:
648: final = ETX;
649:
650: goto controls;
651:
652: }
653:
654: if (!stcmp (intext, "EOT\201")) {
655:
656: final = EOT;
657:
658: goto controls;
659:
660: }
661:
662: if (!stcmp (intext, "ENQ\201")) {
663:
664: final = ENQ;
665:
666: goto controls;
667:
668: }
669:
670: if (!stcmp (intext, "ACK\201")) {
671:
672: final = ACK;
673:
674: goto controls;
675:
676: }
677:
678: if (!stcmp (intext, "BEL\201")) {
679:
680: final = BEL;
681:
682: goto controls;
683:
684: }
685:
686: if (!stcmp (intext, "BS\201")) {
687:
688: final = BS;
689:
690: goto controls;
691:
692: }
693:
694: if (!stcmp (intext, "HT\201")) {
695:
696: final = TAB;
697:
698: goto controls;
699:
700: }
701:
702: if (!stcmp (intext, "LF\201")) {
703:
704: final = LF;
705:
706: goto controls;
707:
708: }
709:
710: if (!stcmp (intext, "VT\201")) {
711:
712: final = VT;
713:
714: goto controls;
715:
716: }
717:
718: if (!stcmp (intext, "FF\201")) {
719:
720: final = FF;
721:
722: goto controls;
723:
724: }
725:
726: if (!stcmp (intext, "CR\201")) {
727:
728: final = CR;
729:
730: goto controls;
731:
732: }
733:
734: if (!stcmp (intext, "SO\201")) {
735:
736: final = SO;
737:
738: goto controls;
739:
740: }
741:
742: if (!stcmp (intext, "SI\201")) {
743:
744: final = SI;
745:
746: goto controls;
747:
748: }
749:
750: if (!stcmp (intext, "DLE\201")) {
751:
752: final = DLE;
753:
754: goto controls;
755:
756: }
757:
758: if (!stcmp (intext, "DC1\201")) {
759:
760: final = DC1;
761:
762: goto controls;
763:
764: }
765:
766: if (!stcmp (intext, "DC2\201")) {
767:
768: final = DC2;
769:
770: goto controls;
771:
772: }
773:
774: if (!stcmp (intext, "DC3\201")) {
775:
776: final = DC3;
777:
778: goto controls;
779:
780: }
781:
782: if (!stcmp (intext, "DC4\201")) {
783:
784: final = DC4;
785:
786: goto controls;
787:
788: }
789:
790: if (!stcmp (intext, "NAK\201")) {
791:
792: final = NAK;
793:
794: goto controls;
795:
796: }
797:
798: if (!stcmp (intext, "SYN\201")) {
799:
800: final = SYN;
801:
802: goto controls;
803:
804: }
805:
806: if (!stcmp (intext, "ETB\201")) {
807:
808: final = ETB;
809:
810: goto controls;
811:
812: }
813:
814: if (!stcmp (intext, "CAN\201")) {
815:
816: final = CAN;
817:
818: goto controls;
819:
820: }
821:
822: if (!stcmp (intext, "EM\201")) {
823:
824: final = EM;
825:
826: goto controls;
827:
828: }
829:
830: if (!stcmp (intext, "SUB\201")) {
831:
832: final = SUB;
833:
834: goto controls;
835:
836: }
837:
838: if (!stcmp (intext, "ESC\201")) {
839:
840: final = ESC;
841:
842: goto controls;
843:
844: }
845:
846: if (!stcmp (intext, "FS\201")) {
847:
848: final = FS;
849:
850: goto controls;
851:
852: }
853:
854: if (!stcmp (intext, "GS\201")) {
855:
856: final = GS;
857:
858: goto controls;
859:
860: }
861:
862:
863: if (!stcmp (intext, "RS\201")) {
864:
865: final = RS;
866:
867: goto controls;
868:
869: }
870:
871: if (!stcmp (intext, "US\201")) {
872:
873: final = US;
874:
875: goto controls;
876:
877: }
878:
879: if (!stcmp (intext, "DEL\201")) {
880:
881: final = DEL;
882:
883: goto controls;
884:
885: }
886:
887: /* DECKPAM Keypad Application Mode */
888: if (!stcmp (intext, "DECKPAM\201")) {
889:
890: final = '=';
891:
892: goto end;
893:
894: }
895:
896: /* DECKPNM Keypad Numeric Mode */
897: if (!stcmp (intext, "DECKPNM\201")) {
898:
899: final = '>';
900:
901: goto end;
902:
903: }
904:
905: /* DECLL Load LEDs */
906: if (!stcmp (intext, "DECLL\201")) {
907:
908: csi = TRUE;
909: final = 'q';
910:
911: goto end;
912:
913: }
914:
915: /* DECRC Restore Cursor */
916: if (!stcmp (intext, "DECRC\201")) {
917:
918: final = '8';
919:
920: goto end;
921:
922: }
923:
924: /* DECSC Save Cursor */
925: if (!stcmp (intext, "DECSC\201")) {
926:
927: final = '7';
928:
929: goto end;
930:
931: }
932:
933: /* DECSTBM Set Top & Bottom Margins */
934: if (!stcmp (intext, "TBM\201") ||
935:
936: !stcmp (intext, "DECSTBM\201")) {
937:
938: csi = TRUE;
939: final = 'r';
940:
941: goto end;
942:
943: }
944:
945: /* ZAS Alternate Screen */
946: if (!stcmp (intext, "ZAS\201")) {
947:
948: csi = TRUE;
949: final = '~';
950:
951: goto end;
952:
953: }
954:
955: return; /* code not recognized */
956:
957: controls:
958: outtext[0] = final;
959: outtext[1] = EOL;
960:
961: write_m (outtext);
962:
963: return;
964:
965: end:
966:
967: outtext[0] = ESC;
968:
969: if (csi++) outtext[1] = '[';
970:
971: while (++i < l) {
972:
973: if ((outtext[csi] = intext[i]) == DELIM) outtext[csi] = ';';
974:
975: csi++;
976:
977: }
978:
979: outtext[csi++] = final;
980: outtext[csi] = EOL;
981:
982: write_m (outtext);
983:
984: return;
985: } /* end of write_f() */
986:
987: /* Output on HOME device */
988: void writeHOME (char *text)
989: {
990:
991: struct winsize terminal_window;
992: static char initflag = TRUE; /* initialisation flag */
993: static char esc = 0; /* esc processing flag */
994: static char dcs = 0; /* device control processing flag */
995:
996: static short args[ARGS_IN_ESC];
997: static short argcnt = 0;
998: static short noargs = TRUE;
999: static char tmp[512];
1000: static short foreground = TRUE; /* foreground flag */
1001: static struct vtstyp *vts;
1002:
1003: /* external struct vtstyp *screen; active screen */
1004: static struct vtstyp *altscr; /* background screen */
1005: static struct vtstyp *zases[MAXZAS];
1006: static int zaslevel = 0;
1007:
1008: /* SGR and CSI=cF have ***different*** color codes */
1009: #ifdef COLOR
1010: static char coltrans[8] =
1011: {0, 4, 2, 6, 1, 5, 3, 7};
1012:
1013: #endif /* COLOR */
1014:
1015:
1016: short tmpx;
1017: register int ch;
1018: register int j;
1019: register int i;
1020: short k;
1021:
1022: /* we assume the HOME device is an ASCII machine according
1023: * to ANSI X3.4, X3.64 etc with 24 lines and 80 columns
1024: * so we look not only at controls as the MUMPS X11.1-1984
1025: * demands, but as well at esc sequences and device control
1026: * strings.
1027: *
1028: * In addition we assume, that the terminal cannot handle
1029: * tab_clear (CSI 3g) nor tab_set (ESC H) so these functions
1030: * are emulated here. For most terminals that might
1031: * not be neccesary. With 'PROC_TAB' we may switch versions.
1032: *
1033: * We support the VT100 on PC-"Terminals"
1034: * where there is no TBM so we have to emulate
1035: * scoll up /down with LF,RI and autowrap. SGR is somewhat
1036: * crazy on the PC and there is a lot of code to fix that.
1037: * The PC completely ignores SGRs it does not fully recognize.
1038: * E.g. SGR(7,4) will not work while SGR(4,7) at least inverts
1039: * the display.
1040: * CSI 10 p (invert INVERS at active position)
1041: * is being emulated too.
1042: * We emulate the terminal software so we have always an image
1043: * of the screen in memory. That enables us to have features like
1044: * CSI 0 ~ (private sequence: change screen)
1045: * CSI 1 ~ (private sequence: output to foreground screen)
1046: * CSI 2 ~ (private sequence: output to background screen)
1047: * CSI 3 ~ (private sequence: save foreground to background)
1048: * CSI 4 ~ (private sequence: screen restore)
1049: * and the 'hardcopy function'
1050: */
1051: if (initflag) {
1052:
1053: /* TODO: why are we casting to void here? */
1054: (void) ioctl(STDOUT_FILENO, TIOCGWINSZ, &terminal_window);
1055:
1056: n_lines = terminal_window.ws_row;
1057: n_columns = terminal_window.ws_col;
1058:
1059: screen = (struct vtstyp *) calloc (1, sizeof (struct vtstyp));
1060:
1061: ris (screen);
1062: altscr = (struct vtstyp *) calloc (1, sizeof (struct vtstyp));
1063:
1064: ris (altscr);
1065: initflag = FALSE;
1066:
1067: }
1068:
1069: opnfile[HOME] = stdout;
1070: tmpx = 0;
1071: j = 0;
1072:
1073: while ((ch = text[j++]) != EOL) {
1074:
1075: if (ch == NUL) continue;
1076:
1077: if (tmpx > 480) {
1078:
1079: tmp[tmpx] = EOL;
1080: tmpx = 0;
1081:
1082: if (foreground) m_output (tmp);
1083:
1084: }
1085:
1086:
1087: if (RightMargin && xpos[HOME] > RightMargin && esc == 0) {
1088:
1089: --j;
1090:
1091: tmp[tmpx++] = CR;
1092: xpos[HOME] = 0;
1093: ch = LF;
1094:
1095: }
1096:
1097: /* what in the name of good and holy is this macro abuse nonsense? */
1098:
1099: #ifdef PROC_TAB
1100: if (ch != TAB) tmp[tmpx++] = ch;
1101: #else
1102: tmp[tmpx++] = ch;
1103: #endif /* PROC_TAB */
1104:
1105:
1106: if (UNSIGN (ch) >= SP && ch != DEL) { /* printable characters */
1107:
1108: if (esc == 0) { /* no esc/dcs in progress; wrap-around */
1109:
1110: (*screen).screenx[(unsigned int) (*screen).sclines[ypos[HOME]]][xpos[HOME]] = ch;
1111:
1112: if ((*screen).savarg == FALSE) {
1113:
1114:
1115: #ifdef COLOR
1116: (*screen).screenc[(unsigned int) (*screen).sclines[ypos[HOME]]][xpos[HOME]] = (*screen).col;
1117: #endif /* COLOR */
1118:
1119: (*screen).screena[(unsigned int) (*screen).sclines[ypos[HOME]]][xpos[HOME]] = (*screen).att;
1120:
1121: }
1122:
1123: if (dcs == 0 && ++xpos[HOME] >= n_columns) {
1124:
1125: xpos[HOME] = 0;
1126:
1127: if ((*screen).rollflag) goto pLF;
1128:
1129: ypos[HOME] = (*screen).sc_lo;
1130:
1131: }
1132:
1133: continue;
1134:
1135: }
1136:
1137: if (esc == 1) { /* esc_sequence in progress */
1138:
1139: if (ch == '[') { /* CSI command string starts */
1140: esc = 2;
1141: continue;
1142: }
1143: else if (ch == 'H') { /* HTS set tab at $X */
1144: (*screen).tabs[xpos[HOME]] = 1;
1145: }
1146: else if (ch == 'M') { /* RI cursor up *//* upper margin of scroll area: scroll down */
1147:
1148: if (ypos[HOME] == (*screen).sc_up) {
1149:
1150: k = (*screen).sclines[(*screen).sc_lo];
1151:
1152: for (i = (*screen).sc_lo; i > (*screen).sc_up; i--) (*screen).sclines[i] = (*screen).sclines[i - 1];
1153:
1154: (*screen).sclines[(*screen).sc_up] = k;
1155:
1156: for (i = 0; i < n_columns; i++) {
1157:
1158: (*screen).screenx[k][i] = SP;
1159: (*screen).screena[k][i] = (*screen).att;
1160:
1161:
1162: #ifdef COLOR
1163: (*screen).screenc[k][i] = (*screen).col;
1164: #endif /* COLOR */
1165:
1166: }
1167:
1168: if (foreground) {
1169:
1170: tmp[tmpx - 2] = EOL;
1171: m_output (tmp);
1172:
1173: tmpx = 0;
1174: part_ref (screen, (*screen).sc_up, (*screen).sc_lo);
1175:
1176: }
1177: }
1178:
1179: if (ypos[HOME] != 0 && ypos[HOME] != (*screen).sc_up) ypos[HOME]--;
1180:
1181: tmp[tmpx++] = ESC;
1182: tmp[tmpx++] = '[';
1183:
1184: if (ypos[HOME] > 8) tmp[tmpx++] = (1 + ypos[HOME]) / 10 + '0';
1185:
1186: tmp[tmpx++] = (1 + ypos[HOME]) % 10 + '0';
1187:
1188: if (xpos[HOME] > 0) {
1189:
1190: tmp[tmpx++] = ';';
1191:
1192: if (xpos[HOME] > 8) tmp[tmpx++] = (1 + xpos[HOME]) / 10 + '0';
1193:
1194: tmp[tmpx++] = (1 + xpos[HOME]) % 10 + '0';
1195:
1196: }
1197:
1198: tmp[tmpx++] = 'H';
1199:
1200: }
1201: else if (ch == 'E') { /* NEL new line */
1202:
1203: /* RI */
1204:
1205: xpos[HOME] = 0;
1206: esc = 0;
1207:
1208: goto pLF;
1209:
1210: }
1211: else if (ch == 'Q') { /* DCS Device control string */
1212: dcs = 1;
1213: }
1214: else if (ch == '\\') { /* ST String terminator (DCS) */
1215: dcs = 0;
1216: }
1217: else if (ch == '7') { /* DEC CS Cursor Save */
1218:
1219: (*screen).csx[(*screen).cs] = xpos[HOME];
1220: (*screen).csy[(*screen).cs] = ypos[HOME];
1221:
1222: if (++((*screen).cs) >= CSLEN) (*screen).cs = CSLEN - 1;
1223:
1224: }
1225: else if (ch == '8') { /* DEC CRST Cursor Restore */
1226:
1227: if (--((*screen).cs) <= 0) (*screen).cs = 0;
1228:
1229: xpos[HOME] = (*screen).csx[(*screen).cs];
1230: ypos[HOME] = (*screen).csy[(*screen).cs];
1231:
1232: /* make sure cursor is at desired position */
1233: tmp[tmpx++] = ESC;
1234: tmp[tmpx++] = '[';
1235:
1236: if (ypos[HOME] > 8) tmp[tmpx++] = (1 + ypos[HOME]) / 10 + '0';
1237:
1238: tmp[tmpx++] = (1 + ypos[HOME]) % 10 + '0';
1239:
1240: if (xpos[HOME] > 0) {
1241:
1242: tmp[tmpx++] = ';';
1243:
1244: if (xpos[HOME] > 8) tmp[tmpx++] = (1 + xpos[HOME]) / 10 + '0';
1245:
1246: tmp[tmpx++] = (1 + xpos[HOME]) % 10 + '0';
1247:
1248: }
1249:
1250: tmp[tmpx++] = 'H';
1251:
1252: }
1253: else if (ch == 'c') { /* RIS Reset to initial state */
1254:
1255: esc = 0;
1256: dcs = 0;
1257: foreground = TRUE;
1258: xpos[HOME] = 0;
1259: ypos[HOME] = 0;
1260:
1261: ris (screen);
1262:
1263: }
1264: else if (ch == '(' || ch == ')') {
1265: continue;
1266: }
1267:
1268: esc = 0;
1269:
1270: continue;
1271:
1272: } /* end if (esc==1) */
1273:
1274: /* command string (esc [) in progress */
1275: /* numeric arguments ? */
1276: if (ch >= '0' && ch <= '9') {
1277:
1278: noargs = FALSE;
1279: args[argcnt] = args[argcnt] * 10 + ch - '0';
1280:
1281: continue;
1282:
1283: }
1284:
1285: if (ch == ';') {
1286:
1287: args[++argcnt] = 0;
1288:
1289: continue;
1290:
1291: }
1292:
1293: if (ch == '=') {
1294: esc = 3;
1295: continue;
1296: } /* color sequence */
1297:
1298: if (esc == 3) {
1299:
1300: esc = 0;
1301:
1302:
1303: #ifdef COLOR
1304: if (ch == 'F') { /* foreground color */
1305:
1306: (*screen).col = (((*screen).col & ~017) | (args[0] & 017));
1307:
1308: tmp[tmpx++] = ESC; /* reverse background */
1309: tmp[tmpx++] = '[';
1310: tmp[tmpx++] = '=';
1311:
1312: if (args[0] > 9) tmp[tmpx++] = '0' + (args[0] / 10);
1313:
1314: tmp[tmpx++] = '0' + (args[0] % 10);
1315: tmp[tmpx++] = 'I';
1316:
1317: continue;
1318:
1319: }
1320:
1321: if (ch == 'G') { /* background color */
1322:
1323: (*screen).col = (((*screen).col & 017) | (args[0] * 16));
1324:
1325: tmp[tmpx++] = ESC; /* reverse forground */
1326: tmp[tmpx++] = '[';
1327: tmp[tmpx++] = '=';
1328:
1329: if (args[0] > 9) tmp[tmpx++] = '0' + (args[0] / 10);
1330:
1331: tmp[tmpx++] = '0' + (args[0] % 10);
1332: tmp[tmpx++] = 'H';
1333:
1334: continue;
1335:
1336: }
1337: #endif /* COLOR */
1338:
1339:
1340: continue;
1341:
1342: } /* if (esc == 3) */
1343:
1344: if (ch < '@') continue;
1345:
1346: /* check final characters */
1347: if (ch == 'A') { /* CUU cursor up */
1348:
1349: do {
1350:
1351: if (--ypos[HOME] < 0) ypos[HOME] = 0;
1352:
1353: }
1354: while (--args[0] > 0);
1355:
1356: }
1357: else if (ch == 'B') { /* CUD cursor down */
1358:
1359: do {
1360:
1361: if (++ypos[HOME] >= (n_lines - 1)) ypos[HOME] = (n_lines - 1);
1362:
1363: }
1364: while (--args[0] > 0);
1365:
1366: }
1367: else if (ch == 'C') { /* CUF cursor right */
1368:
1369: do {
1370:
1371: if (++xpos[HOME] >= n_columns) xpos[HOME] = (n_columns - 1);
1372:
1373: }
1374: while (--args[0] > 0);
1375:
1376: }
1377: else if (ch == 'D') { /* CUB cursor left */
1378:
1379: do {
1380:
1381: if (--xpos[HOME] < 0) xpos[HOME] = 0;
1382:
1383: }
1384: while (--args[0] > 0) ;
1385:
1386: }
1387: else if (ch == 'H') { /* CUP cursor position */
1388:
1389: i = --args[0];
1390:
1391: if (i < 0) i = 0;
1392: if (i <= n_lines) ypos[HOME] = i;
1393:
1394: i = --args[1];
1395:
1396: if (i < 0) i = 0;
1397: if (i < n_columns) xpos[HOME] = i;
1398:
1399: }
1400: else if (ch == 'K') { /* EL erase line */
1401:
1402: int k;
1403:
1404: i = 0;
1405: k = n_columns;
1406:
1407: if (args[0] == 0) i = xpos[HOME];
1408: if (args[0] == 1) k = xpos[HOME] + 1;
1409:
1410: while (i < k) {
1411:
1412: (*screen).screenx[(unsigned int) (*screen).sclines[ypos[HOME]]][i] = SP;
1413: (*screen).screena[(unsigned int) (*screen).sclines[ypos[HOME]]][i] = 0; /* not 'att' */
1414:
1415:
1416: #ifdef COLOR
1417: (*screen).screenc[(unsigned int) (*screen).sclines[ypos[HOME]]][i] = (*screen).col;
1418: #endif /* COLOR */
1419:
1420: i++;
1421:
1422: }
1423: }
1424: else /* TODO: this bogosity must go away. */
1425:
1426:
1427: ED:
1428: if (ch == 'J') { /* ED erase display */
1429:
1430: register int k;
1431:
1432: #ifdef COLOR
1433: unsigned char color;
1434: #endif /* COLOR (COLOR is forced on in mpsdef.h or mpsdef0.h) */
1435:
1436: i = 0;
1437: k = n_columns;
1438:
1439: if (args[0] == 0) i = xpos[HOME];
1440: if (args[0] == 1) k = xpos[HOME] + 1;
1441:
1442:
1443: #ifdef COLOR
1444: color = (*screen).col;
1445: #endif /* COLOR */
1446:
1447: while (i < k) { /* clear current line */
1448:
1449: /* TODO: revisit this commented-out section. Was part of the
1450: * original support for terminals larger than 80x25.
1451: * Possibly responsible for screen state corruption?
1452: *
1453: * Ref: issue #95
1454: * https://gitlab.coherent-logic.com/jpw/freem/-/issues/95
1455: */
1456: /*
1457: (*screen).screenx[(unsigned int) (*screen).sclines[ypos[HOME]]][i] = SP;
1458: (*screen).screena[(unsigned int) (*screen).sclines[ypos[HOME]]][i] = 0;*/
1459:
1460: (*screen).screenx[ypos[HOME]][i] = SP;
1461: (*screen).screena[ypos[HOME]][i] = 0; /* not 'att' */
1462:
1463: #ifdef COLOR
1464: (*screen).screenc[ypos[HOME]][i] = color;
1465: #endif /* COLOR */
1466:
1467: i++;
1468:
1469: }
1470:
1471: /* clear rest of screen */
1472: if (args[0] != 1) {
1473:
1474: for (k = ypos[HOME] + 1; k < n_lines; k++) {
1475:
1476: for (i = 0; i < n_columns; i++) {
1477:
1478: /* TODO: revisit; see above */
1479: /* (*screen).screenx[(unsigned int) (*screen).sclines[k]][i] = SP; */
1480: (*screen).screenx[k][i] = SP;
1481: (*screen).screena[k][i] = 0;
1482:
1483:
1484: #ifdef COLOR
1485: (*screen).screenc[k][i] = color;
1486: #endif /* COLOR */
1487:
1488: }
1489:
1490: }
1491:
1492: }
1493:
1494: /* clear beginning of screen */
1495: if (args[0] != 0) {
1496:
1497: for (k = 0; k < ypos[HOME]; k++) {
1498:
1499: for (i = 0; i < n_columns; i++) {
1500:
1501: (*screen).screenx[k][i] = SP;
1502: (*screen).screena[k][i] = 0;
1503:
1504:
1505: #ifdef COLOR
1506: (*screen).screenc[k][i] = color;
1507: #endif /* COLOR */
1508:
1509: }
1510:
1511: }
1512:
1513: }
1514:
1515:
1516: #ifdef SCO
1517: if (foreground) {
1518:
1519: if ((*screen).lin24) tmp[tmpx - 1] = CAN;
1520:
1521: tmp[tmpx] = EOL;
1522: m_output (tmp);
1523:
1524: tmpx = 0;
1525: part_ref (screen, 0, n_lines - 1);
1526:
1527: }
1528: #endif /* SCO */
1529:
1530: }
1531: /* end ED */
1532: else if (ch == 'p') { /* private */
1533:
1534: if (args[0] == 10) {
1535:
1536: /* invert 'inverse' at */
1537: /* current cursor pos. */
1538:
1539: (*screen).screena[(unsigned int) (*screen).sclines[ypos[HOME]]][xpos[HOME]] ^= 0100;
1540:
1541: #ifdef SCO
1542:
1543: /* now we're in the meat of the really bizarre SCO UNIX terminal I/O stuff.
1544: most of this will need to be reworked. */
1545:
1546: if (foreground) {
1547:
1548: k = (*screen).screena[(unsigned int) (*screen).sclines[ypos[HOME]]][xpos[HOME]];
1549:
1550: if (((*screen).att & 01) != (k & 01)) tmp[tmpx++] = (k & 01) ? SO : SI;
1551:
1552: k = scosgr (k, (*screen).bw);
1553:
1554: tmp[tmpx++] = ESC;
1555: tmp[tmpx++] = '[';
1556:
1557: if ((*screen).bw) tmp[tmpx++] = '7';
1558:
1559: tmp[tmpx++] = 'm';
1560: tmp[tmpx++] = ESC;
1561: tmp[tmpx++] = '[';
1562:
1563: if (k & 02) {
1564: tmp[tmpx++] = '1';
1565: tmp[tmpx++] = ';';
1566: } /* SCO !!! Yeah, SCO. What of it? Such a useful comment... */
1567:
1568: if (k & 04) {
1569: tmp[tmpx++] = '3';
1570: tmp[tmpx++] = ';';
1571: }
1572:
1573: if (k & 010) {
1574: tmp[tmpx++] = '4';
1575: tmp[tmpx++] = ';';
1576: }
1577:
1578: if (k & 020) {
1579: tmp[tmpx++] = '5';
1580: tmp[tmpx++] = ';';
1581: }
1582:
1583: if (k & 040) {
1584: tmp[tmpx++] = '6';
1585: tmp[tmpx++] = ';';
1586: }
1587:
1588: if (k & 0100) {
1589: tmp[tmpx++] = '7';
1590: tmp[tmpx++] = ';';
1591: }
1592:
1593: if (k & 0200) {
1594: tmp[tmpx++] = '8';
1595: tmp[tmpx++] = ';';
1596: }
1597:
1598: if (tmp[tmpx - 1] == ';') tmpx--;
1599:
1600: tmp[tmpx++] = 'm';
1601: tmp[tmpx++] = (*screen).screenx[(unsigned int) (*screen).sclines[ypos[HOME]]][xpos[HOME]];
1602: tmp[tmpx++] = ESC;
1603: tmp[tmpx++] = '[';
1604: k = ypos[HOME] + 1;
1605:
1606: if (k > 9) tmp[tmpx++] = k / 10 + '0';
1607:
1608: tmp[tmpx++] = k % 10 + '0';
1609:
1610: if (xpos[HOME]) {
1611:
1612: tmp[tmpx++] = ';';
1613: k = xpos[HOME] + 1;
1614:
1615: if (k > 9) tmp[tmpx++] = k / 10 + '0';
1616:
1617: tmp[tmpx++] = k % 10 + '0';
1618:
1619: }
1620:
1621: tmp[tmpx++] = 'H';
1622:
1623: if (k != screen->att) {
1624:
1625: k = scosgr ((*screen).att, (*screen).bw);
1626:
1627: tmp[tmpx++] = (k & 01) ? SO : SI;
1628: tmp[tmpx++] = ESC;
1629: tmp[tmpx++] = '[';
1630: tmp[tmpx++] = '0';
1631:
1632: if (k & 02) {
1633: tmp[tmpx++] = ';';
1634: tmp[tmpx++] = '1';
1635: } /* SCO !!! Again... what about it? */
1636:
1637: if (k & 04) {
1638: tmp[tmpx++] = ';';
1639: tmp[tmpx++] = '3';
1640: }
1641:
1642: if (k & 010) {
1643: tmp[tmpx++] = ';';
1644: tmp[tmpx++] = '4';
1645: }
1646:
1647: if (k & 020) {
1648: tmp[tmpx++] = ';';
1649: tmp[tmpx++] = '5';
1650: }
1651:
1652: if (k & 040) {
1653: tmp[tmpx++] = ';';
1654: tmp[tmpx++] = '6';
1655: }
1656:
1657: if (k & 0100) {
1658: tmp[tmpx++] = ';';
1659: tmp[tmpx++] = '7';
1660: }
1661:
1662: if (k & 0200) {
1663: tmp[tmpx++] = ';';
1664: tmp[tmpx++] = '8';
1665: }
1666:
1667: tmp[tmpx++] = 'm';
1668:
1669: }
1670:
1671: }
1672: #endif /* SCO */
1673:
1674: }
1675: }
1676: else if (ch == 'r') { /* TBM Top_Bottom Margin */
1677:
1678: register int k;
1679:
1680: if (noargs || ((*screen).sc_up = (--args[0])) <= 0) (*screen).sc_up = 0;
1681:
1682: /* TODO: Revisit. This still appears to be hardcoded to the old fixed terminal size.
1683: * Ref issue #95
1684: */
1685: if (!argcnt || (((*screen).sc_lo = (--args[1])) > 24) || ((*screen).sc_lo == 23 && (*screen).lin24 == TRUE)) {
1686: (*screen).sc_lo = (*screen).lin24 ? 23 : 24;
1687: }
1688:
1689: /* restore old cursor position */
1690: tmp[tmpx++] = ESC;
1691: tmp[tmpx++] = '[';
1692: k = ypos[HOME] + 1;
1693:
1694: if (k > 9) tmp[tmpx++] = k / 10 + '0';
1695:
1696: tmp[tmpx++] = k % 10 + '0';
1697:
1698: if (xpos[HOME]) {
1699:
1700: tmp[tmpx++] = ';';
1701: k = xpos[HOME] + 1;
1702:
1703: if (k > 9) tmp[tmpx++] = k / 10 + '0';
1704:
1705: tmp[tmpx++] = k % 10 + '0';
1706:
1707: }
1708:
1709: tmp[tmpx++] = 'H';
1710:
1711: }
1712: else if (ch == 's') { /* CS Cursor Save */
1713:
1714: (*screen).csx[(*screen).cs] = xpos[HOME];
1715: (*screen).csy[(*screen).cs] = ypos[HOME];
1716: (*screen).cssgr[(*screen).cs] = (*screen).att;
1717:
1718:
1719: #ifdef COLOR
1720: (*screen).cscol[(*screen).cs] = (*screen).col;
1721: #endif /* COLOR */
1722:
1723: if (++((*screen).cs) >= CSLEN) (*screen).cs = CSLEN - 1;
1724:
1725: }
1726: else if (ch == 'u') {
1727:
1728: /* CRST Cursor Unsave (if no args) */
1729: /* those bloody bastards made 'CSI u' and CSI 0 u' */
1730: /* different. flag 'noargs' distinguishes */
1731:
1732: /* bloody bastards, eh? this whole module is a bloody bastard,
1733: * so I seriously have no idea what the hell you're complaining
1734: * about, Mr. ha-Ashkenaz.
1735: */
1736:
1737: if (noargs) {
1738:
1739:
1740: #ifdef COLOR
1741: int color;
1742: #endif /* COLOR */
1743:
1744: if (--((*screen).cs) <= 0) (*screen).cs = 0;
1745:
1746: xpos[HOME] = (*screen).csx[(*screen).cs];
1747: ypos[HOME] = (*screen).csy[(*screen).cs];
1748:
1749: (*screen).att = (*screen).cssgr[(*screen).cs];
1750:
1751:
1752: #ifdef COLOR
1753: (*screen).col = (*screen).cscol[(*screen).cs];
1754: color = (*screen).col;
1755: #endif /* COLOR */
1756:
1757: /* make sure cursor is at desired position */
1758: tmp[tmpx++] = ESC;
1759: tmp[tmpx++] = '[';
1760:
1761: if (ypos[HOME] > 8) tmp[tmpx++] = (1 + ypos[HOME]) / 10 + '0';
1762:
1763: tmp[tmpx++] = (1 + ypos[HOME]) % 10 + '0';
1764:
1765: if (xpos[HOME] > 0) {
1766:
1767: tmp[tmpx++] = ';';
1768:
1769: if (xpos[HOME] > 8) tmp[tmpx++] = (1 + xpos[HOME]) / 10 + '0';
1770:
1771: tmp[tmpx++] = (1 + xpos[HOME]) % 10 + '0';
1772:
1773: }
1774:
1775: tmp[tmpx++] = 'H';
1776:
1777:
1778: #ifdef COLOR
1779:
1780: /* make sure cursor has right color */
1781: tmp[tmpx++] = ESC; /* background color */
1782: tmp[tmpx++] = '[';
1783: tmp[tmpx++] = '=';
1784:
1785: if (color / 16 > 9) tmp[tmpx++] = '0' + (color / 16 / 10);
1786:
1787: tmp[tmpx++] = '0' + (color / 16 % 10);
1788: tmp[tmpx++] = 'G';
1789: tmp[tmpx++] = ESC; /* reverse foreground col */
1790: tmp[tmpx++] = '[';
1791: tmp[tmpx++] = '=';
1792:
1793: if (color / 16 > 9) tmp[tmpx++] = '0' + (color / 16 / 10);
1794:
1795: tmp[tmpx++] = '0' + (color / 16 % 10);
1796: tmp[tmpx++] = 'H';
1797: tmp[tmpx++] = ESC; /* foreground color */
1798: tmp[tmpx++] = '[';
1799: tmp[tmpx++] = '=';
1800:
1801: if (color % 16 > 9) tmp[tmpx++] = '0' + (color % 16 / 10);
1802:
1803: tmp[tmpx++] = '0' + (color % 16 % 10);
1804: tmp[tmpx++] = 'F';
1805: tmp[tmpx++] = ESC; /* reverse background col */
1806: tmp[tmpx++] = '[';
1807: tmp[tmpx++] = '=';
1808:
1809: if (color % 16 > 9) tmp[tmpx++] = '0' + (color % 16 / 10);
1810:
1811: tmp[tmpx++] = '0' + (color % 16 % 10);
1812: tmp[tmpx++] = 'I';
1813: #endif /* COLOR */
1814:
1815: }
1816: else if (args[0] == 0) {
1817:
1818: (*screen).lin24 = FALSE;
1819:
1820: if ((*screen).sc_lo == 23) (*screen).sc_lo = 24;
1821:
1822: }
1823: else if (args[0] == 1) {
1824:
1825: (*screen).lin24 = TRUE;
1826:
1827: if ((*screen).sc_lo == 24) (*screen).sc_lo = 23;
1828:
1829: }
1830: else if (args[0] == 8) {
1831: (*screen).rollflag = FALSE;
1832: }
1833: else if (args[0] == 9) {
1834: (*screen).rollflag = TRUE;
1835: }
1836: #ifdef SCO
1837: else if (args[0] == 20) {
1838:
1839: (*screen).bw = FALSE;
1840:
1841: if (foreground) {
1842:
1843: tmp[tmpx] = EOL;
1844: m_output (tmp);
1845:
1846: tmpx = 0;
1847: part_ref (screen, 0, n_lines - 1);
1848:
1849: }
1850:
1851: }
1852: else if (args[0] == 21) {
1853:
1854: (*screen).bw = TRUE;
1855:
1856: if (foreground) {
1857:
1858: tmp[tmpx] = EOL;
1859: m_output (tmp);
1860:
1861: tmpx = 0;
1862: part_ref (screen, 0, n_lines - 1);
1863:
1864: }
1865:
1866: }
1867: #endif /* SCO */
1868:
1869: }
1870: else if (ch == 'X') { /* ECH Erase Character */
1871:
1872: if ((k = args[0]) < 1) k = 1;
1873: if ((k + xpos[HOME]) > n_columns) k = n_columns - xpos[HOME];
1874:
1875: i = xpos[HOME];
1876: k = i + k;
1877:
1878: while (i < k) {
1879:
1880: (*screen).screenx[(unsigned int) (*screen).sclines[ypos[HOME]]][i] = SP;
1881: (*screen).screena[(unsigned int) (*screen).sclines[ypos[HOME]]][i] = 0; /* not 'att' */
1882:
1883:
1884: #ifdef COLOR
1885: (*screen).screenc[(unsigned int) (*screen).sclines[ypos[HOME]]][i] = (*screen).col;
1886: #endif /* COLOR */
1887:
1888: i++;
1889:
1890: }
1891:
1892: } else if (ch == 'g') { /* TBC Tabulation clear */
1893:
1894: if (args[0] == 3) {
1895: /* clear all */
1896: for (i = 0; i < n_columns; (*screen).tabs[i++] = 0) ;
1897: }
1898: else if (args[0] == 0) {
1899: /* clear one */
1900: (*screen).tabs[xpos[HOME]] = 0;
1901: }
1902:
1903:
1904: #ifdef SCO
1905: while (tmpx >= 0) if (tmp[--tmpx] == ESC) break;
1906:
1907: tmp[tmpx] = NUL;
1908: ch = NUL;
1909: #endif /* SCO */
1910:
1911: }
1912: else if (ch == 'm') { /* SGR Select Graphic Rendition */
1913:
1914: (*screen).att &= 01; /* clear att */
1915:
1916:
1917: #ifdef SCO
1918: while (tmpx > 0 && tmp[--tmpx] != ESC);
1919:
1920: ch = CAN;
1921: #endif /* SCO */
1922:
1923: i = argcnt;
1924:
1925: while (i >= 0) {
1926:
1927: if (((*screen).savarg = (args[i] == 50))) continue;
1928:
1929:
1930: #ifdef SCO /* process save SGR(1) in position of SGR(2) */
1931: if (args[i] == 1) args[i] = 2;
1932: #endif /* SCO */
1933:
1934: #ifdef COLOR
1935: if (args[i] > 29 && args[i] < 38) { /* foregr.color */
1936: (*screen).col = ((*screen).col & ~017) | coltrans[args[i] - 30];
1937: }
1938:
1939: if (args[i] > 39 && args[i] < 48) { /* backgr.color */
1940: (*screen).col = (((*screen).col & 017) | (coltrans[args[i] - 40] * 16));
1941: }
1942:
1943: #endif /* COLOR */
1944:
1945: if (args[i] > 1 && args[i] < 9) (*screen).att |= (1 << (args[i] - 1));
1946: if (args[i] == 0) (*screen).att &= 01; /* clear att */
1947:
1948: i--;
1949:
1950: }
1951:
1952: #ifdef SCO
1953: tmp[tmpx++] = ESC;
1954: tmp[tmpx++] = '[';
1955: if ((*screen).bw) tmp[tmpx++] = '7';
1956:
1957: tmp[tmpx++] = 'm';
1958:
1959:
1960: #ifdef COLOR
1961: tmp[tmpx++] = ESC;
1962: tmp[tmpx++] = '[';
1963: tmp[tmpx++] = '=';
1964: if ((*screen).col / 16 > 9) tmp[tmpx++] = '0' + ((*screen).col / 16 / 10);
1965:
1966: tmp[tmpx++] = '0' + ((*screen).col / 16 % 10);
1967: tmp[tmpx++] = 'G';
1968: tmp[tmpx++] = ESC;
1969: tmp[tmpx++] = '[';
1970: tmp[tmpx++] = '=';
1971: if ((*screen).col / 16 > 9) tmp[tmpx++] = '0' + ((*screen).col / 16 / 10);
1972:
1973: tmp[tmpx++] = '0' + ((*screen).col / 16 % 10);
1974: tmp[tmpx++] = 'H';
1975: tmp[tmpx++] = ESC;
1976: tmp[tmpx++] = '[';
1977: tmp[tmpx++] = '=';
1978: if ((*screen).col % 16 > 9) tmp[tmpx++] = '0' + ((*screen).col % 16 / 10);
1979:
1980: tmp[tmpx++] = '0' + ((*screen).col % 16 % 10);
1981: tmp[tmpx++] = 'F';
1982: tmp[tmpx++] = ESC;
1983: tmp[tmpx++] = '[';
1984: tmp[tmpx++] = '=';
1985: if ((*screen).col % 16 > 9) tmp[tmpx++] = '0' + ((*screen).col % 16 / 10);
1986:
1987: tmp[tmpx++] = '0' + ((*screen).col % 16 % 10);
1988: tmp[tmpx++] = 'I';
1989: #endif /* COLOR */
1990:
1991: if ((*screen).att & ~01) {
1992:
1993: int j;
1994:
1995: j = scosgr ((*screen).att & ~01, (*screen).bw);
1996:
1997: tmp[tmpx++] = ESC;
1998: tmp[tmpx++] = '[';
1999:
2000: if (j & 02) {
2001: tmp[tmpx++] = '1';
2002: tmp[tmpx++] = ';';
2003: }
2004:
2005: if (j & 04) {
2006: tmp[tmpx++] = '3';
2007: tmp[tmpx++] = ';';
2008: }
2009:
2010: if (j & 010) {
2011: tmp[tmpx++] = '4';
2012: tmp[tmpx++] = ';';
2013: }
2014:
2015: if (j & 020) {
2016: tmp[tmpx++] = '5';
2017: tmp[tmpx++] = ';';
2018: }
2019:
2020: if (j & 040) {
2021: tmp[tmpx++] = '6';
2022: tmp[tmpx++] = ';';
2023: }
2024:
2025: if (j & 0100) {
2026: tmp[tmpx++] = '7';
2027: tmp[tmpx++] = ';';
2028: }
2029:
2030: if (j & 0200) {
2031: tmp[tmpx++] = '8';
2032: tmp[tmpx++] = ';';
2033: }
2034:
2035: if (tmp[tmpx - 1] == ';') tmpx--;
2036:
2037: tmp[tmpx++] = 'm';
2038:
2039: }
2040: #endif /* SCO */
2041:
2042: }
2043: else if (ch == 'P') { /* DCH Delete Character */
2044: int j;
2045:
2046: if ((j = args[0]) == 0) j = 1;
2047:
2048: k = (*screen).sclines[ypos[HOME]];
2049:
2050: for (i = xpos[HOME]; i < (n_columns - j); i++) {
2051:
2052: (*screen).screenx[k][i] = (*screen).screenx[k][i + j];
2053: (*screen).screena[k][i] = (*screen).screena[k][i + j];
2054:
2055:
2056: #ifdef COLOR
2057: (*screen).screenc[k][i] = (*screen).screenc[k][i + j];
2058: #endif /* COLOR */
2059:
2060: }
2061:
2062: for (; i < n_columns; i++) {
2063:
2064: (*screen).screenx[k][i] = SP;
2065: (*screen).screena[k][i] = (*screen).att;
2066:
2067:
2068: #ifdef COLOR
2069: (*screen).screenc[k][i] = (*screen).col;
2070: #endif /* COLOR */
2071:
2072: }
2073:
2074:
2075: } else if (ch == '@') { /* ICH Insert Character */
2076: int j;
2077:
2078: if ((j = args[0]) == 0) j = 1;
2079:
2080: k = (*screen).sclines[ypos[HOME]];
2081:
2082: for (i = (n_columns - 1); i >= (xpos[HOME] + j); i--) {
2083:
2084: (*screen).screenx[k][i] = (*screen).screenx[k][i - j];
2085: (*screen).screena[k][i] = (*screen).screena[k][i - j];
2086:
2087:
2088: #ifdef COLOR
2089: (*screen).screenc[k][i] = (*screen).screenc[k][i - j];
2090: #endif /* COLOR */
2091:
2092: }
2093:
2094: for (; i >= xpos[HOME]; i--) {
2095:
2096: (*screen).screenx[k][i] = SP;
2097: (*screen).screena[k][i] = (*screen).att;
2098:
2099:
2100: #ifdef COLOR
2101: (*screen).screenc[k][i] = (*screen).col;
2102: #endif /* COLOR */
2103:
2104: }
2105:
2106: } else if (ch == 'M') { /* DL Delete Line */
2107: int j = args[0];
2108:
2109: do {
2110:
2111: k = (*screen).sclines[ypos[HOME]];
2112:
2113: for (i = ypos[HOME]; i < (*screen).sc_lo; i++) (*screen).sclines[i] = (*screen).sclines[i + 1];
2114:
2115: (*screen).sclines[i] = k;
2116:
2117: for (i = 0; i < n_columns; i++) {
2118:
2119: (*screen).screenx[k][i] = SP;
2120: (*screen).screena[k][i] = (*screen).att;
2121:
2122:
2123: #ifdef COLOR
2124: (*screen).screenc[k][i] = (*screen).col;
2125: #endif /* COLOR */
2126:
2127: }
2128:
2129: } while (--j > 0);
2130:
2131: xpos[HOME] = 0;
2132:
2133:
2134: #ifdef SCO
2135: if (foreground) {
2136:
2137: tmp[tmpx - 1] = CAN; /* do not send DL */
2138: tmp[tmpx] = EOL;
2139: m_output (tmp);
2140:
2141: tmpx = 0;
2142: part_ref (screen, (*screen).sc_up, n_lines - 1);
2143:
2144: }
2145:
2146: #endif /* SCO */
2147:
2148: }
2149: else if (ch == 'L') { /* IL Insert Line */
2150: int j = args[0];
2151:
2152: do {
2153: k = (*screen).sclines[(*screen).sc_lo];
2154:
2155: for (i = (*screen).sc_lo; i > ypos[HOME]; i--) {
2156: (*screen).sclines[i] = (*screen).sclines[i - 1];
2157: }
2158:
2159: (*screen).sclines[ypos[HOME]] = k;
2160:
2161: for (i = 0; i < n_columns; i++) {
2162:
2163: (*screen).screenx[k][i] = SP;
2164: (*screen).screena[k][i] = (*screen).att;
2165:
2166:
2167: #ifdef COLOR
2168: (*screen).screenc[k][i] = (*screen).col;
2169: #endif /* COLOR */
2170:
2171: }
2172: } while (--j > 0);
2173:
2174: xpos[HOME] = 0;
2175:
2176:
2177: #ifdef SCO
2178: if (foreground) {
2179:
2180: tmp[tmpx - 1] = CAN; /* do not send IL */
2181: tmp[tmpx] = EOL;
2182: m_output (tmp);
2183:
2184: tmpx = 0;
2185: part_ref (screen, (*screen).sc_up, n_lines - 1);
2186:
2187: }
2188: #endif /* SCO */
2189:
2190: }
2191: else if (ch == 'S') { /* SU Scroll up */
2192: int j = args[0];
2193:
2194: do {
2195:
2196: k = (*screen).sclines[(*screen).sc_up];
2197:
2198: for (i = (*screen).sc_up; i < (*screen).sc_lo; i++) {
2199: (*screen).sclines[i] = (*screen).sclines[i + 1];
2200: }
2201:
2202: (*screen).sclines[i] = k;
2203:
2204: for (i = 0; i < n_columns; i++) {
2205:
2206: (*screen).screenx[k][i] = SP;
2207: (*screen).screena[k][i] = (*screen).att;
2208:
2209:
2210: #ifdef COLOR
2211: (*screen).screenc[k][i] = (*screen).col;
2212: #endif /* COLOR */
2213:
2214: }
2215:
2216: } while (--j > 0);
2217:
2218:
2219: #ifdef SCO
2220: if (foreground) {
2221:
2222: tmp[tmpx - 1] = 'A'; /* do not send SU */
2223: tmp[tmpx] = EOL;
2224: m_output (tmp);
2225:
2226: tmpx = 0;
2227: part_ref (screen, (*screen).sc_up, n_lines - 1);
2228:
2229: }
2230: #endif /* SCO */
2231:
2232: }
2233: else if (ch == 'T') { /* SD Scroll down */
2234:
2235: int j = args[0];
2236:
2237: do {
2238:
2239: k = (*screen).sclines[(*screen).sc_lo];
2240:
2241: for (i = (*screen).sc_lo; i > (*screen).sc_up; i--) {
2242: (*screen).sclines[i] = (*screen).sclines[i - 1];
2243: }
2244:
2245: (*screen).sclines[i] = k;
2246:
2247: for (i = 0; i < n_columns; i++) {
2248:
2249: (*screen).screenx[k][i] = SP;
2250: (*screen).screena[k][i] = (*screen).att;
2251:
2252:
2253: #ifdef COLOR
2254: (*screen).screenc[k][i] = (*screen).col;
2255: #endif /* COLOR */
2256:
2257: }
2258:
2259: } while (--j > 0);
2260:
2261:
2262: #ifdef SCO
2263:
2264: if (foreground) {
2265:
2266: tmp[tmpx - 1] = 'A'; /* do not send SD */
2267: tmp[tmpx] = EOL;
2268: m_output (tmp);
2269:
2270: tmpx = 0;
2271: part_ref (screen, (*screen).sc_up, n_lines - 1);
2272:
2273: }
2274:
2275: #endif /* SCO */
2276:
2277: } else if (ch == 'Z') { /* CBT Cursor backward tab */
2278:
2279: if ((i = xpos[HOME] - 1) < 1) i = 1;
2280:
2281: do {
2282:
2283: while ((*screen).tabs[--i] == 0) {
2284:
2285: if (i < 0) {
2286: i++;
2287: break;
2288: }
2289:
2290: }
2291:
2292: if (i == 0) break;
2293:
2294: } while (args[0]-- > 0);
2295:
2296: xpos[HOME] = i;
2297:
2298:
2299: #ifdef PROC_TAB
2300: tmp[tmpx++] = CR;
2301:
2302: if ((xpos[HOME] = i) != 0) {
2303:
2304: tmp[tmpx++] = ESC;
2305: tmp[tmpx++] = '[';
2306:
2307: if (i > 9) tmp[tmpx++] = i / 10 + '0';
2308:
2309: tmp[tmpx++] = i % 10 + '0';
2310: tmp[tmpx++] = 'C';
2311:
2312: }
2313:
2314: #endif /* PROC_TAB */
2315:
2316: }
2317:
2318: if (ch != '~') goto zasend;
2319:
2320: /* ZAS Alternate Screen stuff */
2321: /* the following is better programmed with */
2322: /* 'switch' but some compilers do not have */
2323: /* enough power to swallow the implied stack */
2324: /* depth */
2325: /* switch (args[0]) */
2326:
2327: i = args[0];
2328:
2329: if (i == 1) goto zas1;
2330: if (i == 2) goto zas2;
2331: if (i == 3) goto zas3;
2332: if (i == 4) goto zas4;
2333: if (i == 5) goto zas5;
2334: if (i != 0) goto zas6;
2335:
2336: /* zas0: exchange foreground/background */
2337: tmp[tmpx] = EOL;
2338: tmpx = 0;
2339:
2340: if (foreground) m_output (tmp);
2341:
2342: /* exchange parameters of screen */
2343: (*screen).Xpos = xpos[HOME];
2344: (*screen).Ypos = ypos[HOME];
2345:
2346: vts = screen;
2347: screen = altscr;
2348: altscr = vts;
2349:
2350: xpos[HOME] = (*screen).Xpos;
2351: ypos[HOME] = (*screen).Ypos;
2352:
2353:
2354: zas4: /* refresh foreground */
2355:
2356: tmpx = 0;
2357:
2358: if (foreground) part_ref (screen, 0, n_lines - 1);
2359:
2360: goto zasend;
2361:
2362:
2363: zas1: /* foreground screen */
2364:
2365: if (foreground) goto zasend;
2366:
2367: foreground = TRUE;
2368:
2369:
2370: pPRIVATE: /* exchange parameters of screen */
2371:
2372: (*screen).Xpos = xpos[HOME];
2373: (*screen).Ypos = ypos[HOME];
2374:
2375: vts = screen;
2376: screen = altscr;
2377: altscr = vts;
2378:
2379: xpos[HOME] = (*screen).Xpos;
2380: ypos[HOME] = (*screen).Ypos;
2381:
2382: tmpx = 0;
2383:
2384: goto zasend;
2385:
2386:
2387: zas2: /* background screen */
2388:
2389: if (foreground == FALSE) goto zasend;
2390:
2391: tmp[tmpx] = EOL;
2392: m_output (tmp);
2393:
2394: foreground = FALSE;
2395:
2396: goto pPRIVATE;
2397:
2398:
2399: zas3: /* save foreground to back */
2400:
2401: stcpy0 ((char *) altscr, (const char *) screen, sizeof (struct vtstyp));
2402:
2403: goto zasend;
2404:
2405:
2406: zas5: /* push screen */
2407:
2408: if (zaslevel >= MAXZAS) goto zasend;
2409:
2410: vts = (struct vtstyp *) calloc (1, sizeof (struct vtstyp));
2411: zases[zaslevel++] = vts;
2412:
2413: (*screen).Xpos = xpos[HOME];
2414: (*screen).Ypos = ypos[HOME];
2415:
2416: stcpy0 ((char *) vts, (const char *) screen, sizeof (struct vtstyp));
2417:
2418: goto zasend;
2419:
2420:
2421: zas6: /* pop screen */
2422:
2423: if (--zaslevel < 0) {
2424: zaslevel = 0;
2425: goto zasend;
2426: }
2427:
2428: vts = zases[zaslevel];
2429:
2430:
2431: #ifdef SCO
2432: i = (*screen).bw; /* do not pop bw state */
2433: #endif /* SCO */
2434:
2435: stcpy0 ((char *) screen, (const char *) vts, sizeof (struct vtstyp));
2436:
2437:
2438: #ifdef SCO
2439: (*screen).bw = i;
2440: #endif /* SCO */
2441:
2442: xpos[HOME] = (*screen).Xpos;
2443: ypos[HOME] = (*screen).Ypos;
2444:
2445: free (vts);
2446:
2447: goto zas4;
2448: /* end zas6 */
2449:
2450:
2451: zasend: /* stuf we do when we're finished doing other zassy things */
2452:
2453: argcnt = 0;
2454: noargs = TRUE;
2455: esc = 0;
2456:
2457: continue;
2458:
2459: } /* end 'printable' characters */
2460:
2461: if ((esc = (ch == ESC))) {
2462:
2463: for (ch = 0; ch < ARGS_IN_ESC; args[ch++] = 0);
2464:
2465: argcnt = 0;
2466: noargs = TRUE;
2467:
2468: continue;
2469:
2470: }
2471:
2472: if (ch == LF) {
2473:
2474:
2475: pLF:
2476:
2477: if ((ypos[HOME] <= (*screen).sc_up) || (ypos[HOME] > (*screen).sc_lo)) {
2478:
2479: if (++ypos[HOME] >= (n_lines - 1)) {
2480: ypos[HOME] = (n_lines - 1);
2481: }
2482:
2483: if (ch == LF) tmpx--;
2484:
2485: tmp[tmpx++] = ESC;
2486: tmp[tmpx++] = '[';
2487:
2488: if (ypos[HOME] > 8) tmp[tmpx++] = (1 + ypos[HOME]) / 10 + '0';
2489:
2490: tmp[tmpx++] = (1 + ypos[HOME]) % 10 + '0';
2491:
2492: if (xpos[HOME] > 0) {
2493:
2494: tmp[tmpx++] = ';';
2495:
2496: if (xpos[HOME] > 8) tmp[tmpx++] = (1 + xpos[HOME]) / 10 + '0';
2497:
2498: tmp[tmpx++] = (1 + xpos[HOME]) % 10 + '0';
2499:
2500: }
2501:
2502: tmp[tmpx++] = 'H';
2503:
2504: }
2505: else if (ypos[HOME] < (*screen).sc_lo) {
2506:
2507: /* within scroll area */
2508: if (++ypos[HOME] >= (n_lines - 1)) {
2509: ypos[HOME] = (n_lines - 1);
2510: }
2511:
2512: }
2513: else {
2514:
2515: /* lower margin of scroll area: scroll up */
2516: xpos[HOME] = 0;
2517:
2518:
2519: #ifdef SCO
2520: if ((ch != LF) && (!(*screen).lin24) && (ypos[HOME] == (*screen).sc_lo) && (ypos[HOME] == n_lines - 1)) {
2521: continue;
2522: }
2523: #endif /* SCO */
2524:
2525: /* TODO: find out what 'rollflag' is */
2526: /* if ((*screen).rollflag==FALSE) continue; */
2527: k = (*screen).sclines[(*screen).sc_up];
2528:
2529: for (i = (*screen).sc_up; i < (*screen).sc_lo; i++) {
2530: (*screen).sclines[i] = (*screen).sclines[i + 1];
2531: }
2532:
2533: (*screen).sclines[(*screen).sc_lo] = k;
2534:
2535: for (i = 0; i < n_columns; i++) {
2536:
2537: (*screen).screenx[k][i] = SP;
2538: (*screen).screena[k][i] = (*screen).att;
2539:
2540: #ifdef COLOR
2541: (*screen).screenc[k][i] = (*screen).col;
2542: #endif /* COLOR */
2543:
2544: }
2545:
2546:
2547: #ifdef SCO
2548: tmp[tmpx] = EOL;
2549: tmpx = 0;
2550:
2551: if (foreground) {
2552: m_output (tmp);
2553: part_ref (screen, (*screen).sc_up, (*screen).sc_lo);
2554: }
2555: #endif /* SCO */
2556:
2557: }
2558:
2559: continue;
2560:
2561: } /* if (ch == LF) */
2562:
2563: if (ch == CR) {
2564: xpos[HOME] = 0;
2565: continue;
2566: }
2567:
2568: if (ch == BS) {
2569:
2570: if (--xpos[HOME] < 0) xpos[HOME] = 0;
2571:
2572: continue;
2573:
2574: }
2575:
2576: /* FORM FEED: clear screen */
2577: if (ch == FF) {
2578:
2579: xpos[HOME] = 0;
2580: ypos[HOME] = 0;
2581:
2582: ch = 'J';
2583:
2584: tmp[tmpx - 1] = ESC;
2585: tmp[tmpx++] = '[';
2586: tmp[tmpx++] = 'H';
2587: tmp[tmpx++] = ESC;
2588: tmp[tmpx++] = '[';
2589: tmp[tmpx++] = ch;
2590:
2591: args[0] = 0;
2592: noargs = TRUE;
2593: argcnt = 0;
2594:
2595: goto ED;
2596:
2597: }
2598:
2599: if (ch == TAB) {
2600:
2601: k = xpos[HOME];
2602:
2603: if ((i = k + 1) >= n_columns) i = (n_columns - 1);
2604:
2605: while ((*screen).tabs[i] == 0) {
2606:
2607: if (i >= n_columns) {
2608: i = (n_columns - 1);
2609: break;
2610: }
2611:
2612: i++;
2613:
2614: }
2615:
2616:
2617: #ifdef PROC_TAB
2618: if (i != k) {
2619:
2620: tmp[tmpx++] = CR;
2621:
2622: if ((xpos[HOME] = i) != 0) {
2623:
2624: tmp[tmpx++] = ESC;
2625: tmp[tmpx++] = '[';
2626:
2627: if (i > 9) tmp[tmpx++] = i / 10 + '0';
2628:
2629: tmp[tmpx++] = i % 10 + '0';
2630: tmp[tmpx++] = 'C';
2631:
2632: }
2633:
2634: }
2635: #endif /* PROC_TAB */
2636:
2637: continue;
2638: }
2639:
2640: /* SI Shift In */
2641: if (ch == SI) (*screen).att &= ~01; /* clear SO-Bit */
2642:
2643: /* SO Shift Out */
2644: if (ch == SO) (*screen).att |= 01; /* set SO-Bit */
2645:
2646: if (ch == CAN) { /* CANcel ESC_esquence */
2647: esc = argcnt = noargs = 0;
2648: continue;
2649: }
2650:
2651: } /* end while */
2652:
2653: tmp[tmpx] = EOL;
2654:
2655: if (foreground) m_output (tmp);
2656:
2657: return;
2658:
2659: } /* end writeHOME() */
2660:
2661:
2662: #ifdef SCO
2663:
2664: /*att screen attributes byte */
2665: /*bwflag black_on_white flag */
2666: int scosgr (short att, short bwflag)
2667: {
2668:
2669: att = att & ~044; /* suppress SGR(3) and SGR(6) */
2670:
2671: if (att & 0200) return att & 0201; /* no display */
2672: if (bwflag) att ^= 0100; /* toggle inverse */
2673: if (att & 0100) return att & 0121; /* inverse, evtl. incl. blink */
2674: if (att & 032) return att & 033; /* other valid combinations */
2675:
2676: return att;
2677:
2678: } /* end scosgr() */
2679:
2680: #endif /* SCO */
2681:
2682: /* init Screen params */
2683: void ris (struct vtstyp *scr)
2684: {
2685: short i;
2686: short l;
2687:
2688: scr->att = 0;
2689:
2690: #ifdef COLOR
2691: scr->col = 7; /* default color is white on black */
2692: #endif /* COLOR */
2693:
2694: scr->Xpos = 0;
2695: scr->Ypos = 0;
2696:
2697: for (i = 0; i < CSLEN; i++) {
2698: scr->csx[i] = 0;
2699: scr->csy[i] = 0;
2700: }
2701:
2702: scr->cs = 0;
2703: scr->sc_up = 0;
2704: scr->sc_lo = n_lines;
2705:
2706: for (i = 0; i <= n_lines; i++) {
2707:
2708: scr->sclines[i] = i;
2709:
2710: for (l = 0; l < n_columns; l++) {
2711:
2712: scr->screenx[i][l] = SP;
2713: scr->screena[i][l] = 0;
2714:
2715:
2716: #ifdef COLOR
2717: scr->screenc[i][l] = 7; /* default color is white on black */
2718: #endif /* COLOR */
2719:
2720: }
2721:
2722: }
2723:
2724: /* TABS */
2725: for (i = 0; i <= n_columns; i++) scr->tabs[i] = 0;
2726: for (i = 7; i <= n_columns; i += 8) scr->tabs[i] = 1;
2727:
2728: scr->rollflag = TRUE; /* Roll or Page mode */
2729: scr->lin24 = FALSE; /* 24 lines or 25 lines mode (MUST BE FALSE!!!!) */
2730: scr->savarg = FALSE;
2731:
2732: for (i = 0; i < CSLEN; i++) scr->cssgr[i] = FALSE; /* save SGR flag */
2733:
2734: return;
2735:
2736: } /* end ris() */
2737:
2738: /* refresh (foreground) screen partially */
2739: void part_ref (struct vtstyp *scr, short from, short to)
2740: {
2741: short k;
2742: short l;
2743: short max;
2744: unsigned char exa;
2745: unsigned char exc;
2746: short i;
2747: unsigned char *linea;
2748: unsigned char *linex;
2749: unsigned char *linec;
2750: unsigned char ch;
2751: unsigned char tmp[1300];
2752:
2753: /* build up alternate screen */
2754: /* reset SGR,TBM;white on black,go HOME; 25 Lines */
2755: stcpy (tmp, "\017\033[m\033[37;40m\033[r\033[H\033[0u\201");
2756: m_output (tmp);
2757:
2758:
2759: #ifndef PROC_TAB
2760:
2761: k = 0;
2762: i = 0; /* set TABs */
2763:
2764: tmp[k++] = ESC;
2765: tmp[k++] = '[';
2766:
2767: if (from > 8) tmp[k++] = '0' + (from + 1) / 10;
2768:
2769: tmp[k++] = '0' + (from + 1) % 10;
2770: tmp[k++] = 'H';
2771:
2772: for (l = 0; l < n_columns; l++) {
2773:
2774: tmp[k++] = SP;
2775:
2776: if ((*scr).tabs[l]) {
2777:
2778: tmp[k++] = ESC;
2779: tmp[k++] = 'H';
2780:
2781: i = k;
2782:
2783: }
2784:
2785: }
2786:
2787: tmp[i++] = CR;
2788: tmp[i] = EOL;
2789: m_output (tmp);
2790:
2791: #endif /* PROC_TAB */
2792:
2793: k = 0;
2794:
2795: for (i = from; i <= to; i++) {
2796:
2797: tmp[k++] = ESC; /* CUP(i) */
2798: tmp[k++] = '[';
2799:
2800: if (i > 8) tmp[k++] = (i + 1) / 10 + '0';
2801: if (i > 0) tmp[k++] = (i + 1) % 10 + '0';
2802:
2803: tmp[k++] = 'H';
2804:
2805: linex = (*scr).screenx[(unsigned int) (*scr).sclines[i]];
2806: linea = (*scr).screena[(unsigned int) (*scr).sclines[i]];
2807:
2808: #ifdef COLOR
2809: linec = (*scr).screenc[(unsigned int) (*scr).sclines[i]];
2810: #endif /* COLOR */
2811:
2812: for (max = n_columns - 1; max > 0; max--) {
2813:
2814: if (linex[max] != SP) break;
2815: if (linea[max] != linea[max - 1]) break;
2816: if (linec[max] != linec[max - 1]) break;
2817:
2818: }
2819:
2820: exa = ~linea[0]; /* dummy value to trigger argument codes on 1st char */
2821: exc = ~linec[0]; /* dummy value to trigger argument codes on 1st char */
2822:
2823: for (l = 0; l <= max; l++) {
2824:
2825: if (l == (n_columns - 1) && (i == (n_lines))) continue;
2826:
2827: #ifndef LINUX
2828: #ifdef COLOR
2829: if (exc != linec[l]) { /* set color */
2830:
2831: if ((exc / 16) != (linec[l] / 16)) { /* background color */
2832:
2833: tmp[k++] = ESC;
2834: tmp[k++] = '[';
2835: tmp[k++] = '=';
2836: tmp[k++] = '0';
2837:
2838: if (linec[l] / 16 > 9) tmp[k++] = '0' + linec[l] / 16 / 10;
2839:
2840: tmp[k++] = '0' + linec[l] / 16 % 10;
2841: tmp[k++] = 'G';
2842: tmp[k++] = ESC; /* background == reverse foreground */
2843: tmp[k++] = '[';
2844: tmp[k++] = '=';
2845: tmp[k++] = '0';
2846:
2847: if (linec[l] / 16 > 9) tmp[k++] = '0' + linec[l] / 16 / 10;
2848:
2849: tmp[k++] = '0' + linec[l] / 16 % 10;
2850: tmp[k++] = 'H';
2851:
2852: }
2853:
2854: if ((exc % 16) != (linec[l] % 16)) { /* foreground color */
2855:
2856: tmp[k++] = ESC;
2857: tmp[k++] = '[';
2858: tmp[k++] = '=';
2859: tmp[k++] = '0';
2860:
2861: if (linec[l] % 16 > 9) tmp[k++] = '0' + linec[l] % 16 / 10;
2862:
2863: tmp[k++] = '0' + linec[l] % 16 % 10;
2864: tmp[k++] = 'F';
2865: tmp[k++] = ESC; /* foreground == reverse background */
2866: tmp[k++] = '[';
2867: tmp[k++] = '=';
2868: tmp[k++] = '0';
2869:
2870: if (linec[l] % 16 > 9) tmp[k++] = '0' + linec[l] % 16 / 10;
2871:
2872: tmp[k++] = '0' + linec[l] % 16 % 10;
2873: tmp[k++] = 'I';
2874:
2875: }
2876:
2877: exc = linec[l];
2878:
2879: }
2880:
2881: #endif /* COLOR */
2882: #endif /* LINUX */
2883:
2884: if (exa != linea[l]) { /* set attribute */
2885:
2886: short p;
2887: short xatt;
2888:
2889: p = exa;
2890: exa = linea[l];
2891:
2892: if ((p & 01) != (exa & 01)) tmp[k++] = (exa & 01) ? SO : SI;
2893:
2894: if ((p & ~01) != (exa & ~01)) {
2895:
2896: xatt = exa;
2897:
2898:
2899: #ifdef SCO
2900: xatt = scosgr (xatt, (*scr).bw);
2901: #endif /* SCO */
2902:
2903: tmp[k++] = ESC;
2904: tmp[k++] = '[';
2905:
2906:
2907: #ifdef SCO
2908: if ((*scr).bw) tmp[k++] = '7';
2909: #endif /* SCO */
2910:
2911: tmp[k++] = 'm';
2912: tmp[k++] = ESC;
2913: tmp[k++] = '[';
2914:
2915: if (xatt & 02) {
2916:
2917:
2918: #ifdef SCO
2919: tmp[k++] = '1';
2920: #else
2921: tmp[k++] = '2';
2922: #endif /* SCO */
2923:
2924: tmp[k++] = ';';
2925: }
2926:
2927: if (xatt & 04) {
2928: tmp[k++] = '3';
2929: tmp[k++] = ';';
2930: }
2931:
2932: if (xatt & 010) {
2933: tmp[k++] = '4';
2934: tmp[k++] = ';';
2935: }
2936:
2937: if (xatt & 020) {
2938: tmp[k++] = '5';
2939: tmp[k++] = ';';
2940: }
2941:
2942: if (xatt & 040) {
2943: tmp[k++] = '6';
2944: tmp[k++] = ';';
2945: }
2946:
2947: if (xatt & 0100) {
2948: tmp[k++] = '7';
2949: tmp[k++] = ';';
2950: }
2951:
2952: if (xatt & 0200) {
2953: tmp[k++] = '8';
2954: tmp[k++] = ';';
2955: }
2956:
2957: if (tmp[k - 1] == ';') k--;
2958:
2959: tmp[k++] = 'm';
2960:
2961: }
2962:
2963: }
2964:
2965: tmp[k++] = linex[l];
2966:
2967: }
2968:
2969: if (max + 1 < n_columns) {
2970: tmp[k++] = ESC;
2971: tmp[k++] = '[';
2972: tmp[k++] = 'K';
2973: }
2974:
2975: tmp[k] = EOL;
2976: k = mcmnd;
2977: mcmnd = 'w';
2978: ch = (*codptr);
2979: *codptr = ',';
2980:
2981: m_output (tmp);
2982:
2983: *codptr = ch;
2984: mcmnd = k;
2985:
2986: k = 0;
2987:
2988: }
2989:
2990: /* 'saved' cursor position */
2991: /* actual cursor position & actual attribute */
2992: /* 'flush' output */
2993: k = 0;
2994:
2995:
2996: #ifndef SCO
2997:
2998: tmp[k++] = ESC; /* restore CursorSave Position */
2999: tmp[k++] = '[';
3000: i = (*scr).csy[(*scr).cs] + 1;
3001:
3002: if (i > 9) tmp[k++] = '0' + i / 10;
3003:
3004: tmp[k++] = '0' + i % 10;
3005: tmp[k++] = ';';
3006:
3007: i = (*scr).csx[(*scr).cs] + 1;
3008:
3009: if (i > 9) tmp[k++] = '0' + i / 10;
3010:
3011: tmp[k++] = '0' + i % 10;
3012: tmp[k++] = 'H';
3013: tmp[k++] = ESC; /* DEC Cursor SAVE */
3014: tmp[k++] = '7';
3015: tmp[k++] = ESC; /* ANSI (?) Cursor SAVE */
3016: tmp[k++] = '[';
3017: tmp[k++] = 's';
3018: tmp[k++] = ESC; /* restore 24/25 line mode */
3019: tmp[k++] = '[';
3020: tmp[k++] = '0' + (*scr).lin24;
3021: tmp[k++] = 'u';
3022: tmp[k++] = ESC; /* restore Scroll area */
3023: tmp[k++] = '[';
3024:
3025: if (((*scr).sc_up) > 8) tmp[k++] = '0' + ((*scr).sc_up + 1) / 10;
3026:
3027: tmp[k++] = '0' + ((*scr).sc_up + 1) % 10;
3028: tmp[k++] = ';';
3029:
3030: if (((*scr).sc_lo) > 8) tmp[k++] = '0' + ((*scr).sc_lo + 1) / 10;
3031:
3032: tmp[k++] = '0' + ((*scr).sc_lo + 1) % 10;
3033: tmp[k++] = 'r';
3034:
3035: #endif /* not SCO */
3036:
3037: #ifndef LINUX
3038: #ifdef COLOR
3039:
3040: tmp[k++] = ESC; /* restore foreground color */
3041: tmp[k++] = '[';
3042: tmp[k++] = '=';
3043:
3044: if (((*scr).col) % 16 > 9) tmp[k++] = '0' + ((*scr).col) % 16 / 10;
3045:
3046: tmp[k++] = '0' + ((*scr).col) % 16 % 10;
3047: tmp[k++] = 'F';
3048: tmp[k++] = ESC; /* restore reverse background color */
3049: tmp[k++] = '[';
3050: tmp[k++] = '=';
3051:
3052: if (((*scr).col) % 16 > 9) tmp[k++] = '0' + ((*scr).col) % 16 / 10;
3053:
3054: tmp[k++] = '0' + ((*scr).col) % 16 % 10;
3055: tmp[k++] = 'I';
3056: tmp[k++] = ESC; /* restore background color */
3057: tmp[k++] = '[';
3058: tmp[k++] = '=';
3059:
3060: if (((*scr).col) / 16 > 9) tmp[k++] = '0' + ((*scr).col) / 16 / 10;
3061:
3062: tmp[k++] = '0' + ((*scr).col) / 16 % 10;
3063: tmp[k++] = 'G';
3064: tmp[k++] = ESC; /* restore reverse foreground color */
3065: tmp[k++] = '[';
3066: tmp[k++] = '=';
3067:
3068: if (((*scr).col) / 16 > 9) tmp[k++] = '0' + ((*scr).col) / 16 / 10;
3069:
3070: tmp[k++] = '0' + ((*scr).col) / 16 % 10;
3071: tmp[k++] = 'H';
3072:
3073: #endif /* COLOR */
3074: #endif /* LINUX */
3075:
3076: tmp[k++] = ESC; /* restore CursorPosition */
3077: tmp[k++] = '[';
3078:
3079: if (ypos[HOME] > 8) tmp[k++] = '0' + (ypos[HOME] + 1) / 10;
3080:
3081: tmp[k++] = '0' + (ypos[HOME] + 1) % 10;
3082: tmp[k++] = ';';
3083:
3084: if (xpos[HOME] > 8) tmp[k++] = '0' + (xpos[HOME] + 1) / 10;
3085:
3086: tmp[k++] = '0' + (xpos[HOME] + 1) % 10;
3087: tmp[k++] = 'H';
3088:
3089: i = UNSIGN ((*scr).att);
3090:
3091: tmp[k++] = ((i & 01) ? SO : SI);
3092: tmp[k++] = ESC; /* restore graphic attributes */
3093: tmp[k++] = '[';
3094:
3095:
3096: #ifdef SCO
3097:
3098: if ((*scr).bw) tmp[k++] = '7';
3099:
3100: tmp[k++] = 'm';
3101: tmp[k++] = ESC;
3102: tmp[k++] = '[';
3103:
3104: i = scosgr (i, (*scr).bw);
3105:
3106: if (i & 02) {
3107: tmp[k++] = '1';
3108: tmp[k++] = ';';
3109: }
3110:
3111: #else
3112:
3113: if (i & 02) {
3114: tmp[k++] = '2';
3115: tmp[k++] = ';';
3116: }
3117:
3118: #endif /* SCO */
3119:
3120: if (i & 04) {
3121: tmp[k++] = '3';
3122: tmp[k++] = ';';
3123: }
3124:
3125: if (i & 010) {
3126: tmp[k++] = '4';
3127: tmp[k++] = ';';
3128: }
3129:
3130: if (i & 020) {
3131: tmp[k++] = '5';
3132: tmp[k++] = ';';
3133: }
3134:
3135: if (i & 040) {
3136: tmp[k++] = '6';
3137: tmp[k++] = ';';
3138: }
3139:
3140: if (i & 0100) {
3141: tmp[k++] = '7';
3142: tmp[k++] = ';';
3143: }
3144:
3145: if (i & 0200) {
3146: tmp[k++] = '8';
3147: tmp[k++] = ';';
3148: }
3149:
3150: if (tmp[k - 1] == ';') k--;
3151:
3152: tmp[k++] = 'm';
3153: tmp[k] = EOL;
3154:
3155: k = mcmnd;
3156: mcmnd = 0;
3157:
3158: m_output (tmp);
3159:
3160: mcmnd = k;
3161:
3162: return;
3163:
3164: } /* end part_ref() */
3165:
3166: /* delayed write for higher system throughput */
3167: void m_output (char *text)
3168: {
3169: static char buffer[2048];
3170: static int p = 0;
3171: char *G;
3172: int i;
3173: int ch;
3174:
3175: if (io == HOME) opnfile[io] = stdout;
3176:
3177: G = SIflag[io] ? G0O[io] : G1O[io];
3178:
3179: i = 0;
3180:
3181: while ((ch = text[i++]) != EOL) {
3182:
3183: ch = UNSIGN (ch);
3184:
3185: if (ESCflag[io] == FALSE && ch >= NUL && ch < 255) ch = G[ch];
3186:
3187: buffer[p++] = ch;
3188:
3189: if (ch == SI) {
3190: SIflag[io] = TRUE;
3191: G = G0O[io];
3192: }
3193:
3194: if (ch == SO) {
3195: SIflag[io] = FALSE;
3196: G = G1O[io];
3197: }
3198:
3199: if (ch == ESC) {
3200: ESCflag[io] = TRUE;
3201: continue;
3202: }
3203:
3204: if (ch == '[' && ESCflag[io]) {
3205: ESCflag[io] = 2;
3206: continue;
3207: }
3208:
3209: if (ch >= '@' && ch < DEL) ESCflag[io] = FALSE;
3210: if (ch != NUL) continue;
3211:
3212: fputs (buffer, opnfile[io]);
3213:
3214: p = 0; /* NUL needs special treatment */
3215:
3216: fputc (NUL, opnfile[io]); /* 'cause unix uses it as delim */
3217:
3218: }
3219:
3220: buffer[p] = NUL;
3221:
3222: if (mcmnd == 'w' && *codptr == ',' && (p < 1536)) return;
3223:
3224: if (fm_nodelay[io]) {
3225:
3226: if (setjmp (sjbuf)) {
3227: merr_raise (NOWRITE);
3228: goto done;
3229: }
3230:
3231: sig_attach (SIGALRM, &ontimo);
3232: alarm (3);
3233:
3234: }
3235:
3236: fputs (buffer, opnfile[io]);
3237:
3238: p = 0;
3239:
3240: if (mcmnd == '*') fputc (EOL, opnfile[io]); /* special treatment for EOL */
3241: if (demomode) fputc (d0char, opnfile[io]);
3242:
3243: fflush (opnfile[io]);
3244:
3245:
3246: done:
3247:
3248: alarm (0); /* reset alarm request */
3249:
3250: return;
3251:
3252: } /* end of m_output() */
3253:
3254:
3255: void write_m (char *text)
3256: {
3257: static char esc = 0; /* esc processing flag */
3258: static char tmp[512];
3259: register int i;
3260: register int j;
3261: register int ch;
3262:
3263: if (io == HOME) {
3264:
3265: opnfile[HOME] = stdout;
3266:
3267: if (frm_filter == FALSE) {
3268: writeHOME (text);
3269: return;
3270: }
3271:
3272: }
3273:
3274: /* 'normal' output for devices other than HOME */
3275: j = 0;
3276: i = 0;
3277:
3278: while ((ch = text[j++]) != EOL) {
3279:
3280: tmp[i++] = ch;
3281:
3282: if (ch >= SP) {
3283:
3284: if (esc == 0) {
3285: xpos[io]++;
3286: continue;
3287: }
3288:
3289: if (ch == '[') {
3290: esc = 2;
3291: continue;
3292: }
3293:
3294: if (ch >= '@' || esc == 1) esc = 0;
3295:
3296: continue;
3297:
3298: }
3299:
3300: esc = (ch == ESC);
3301:
3302: if (ch == LF) {
3303:
3304: ypos[io]++;
3305:
3306: if (crlf[io]) xpos[io] = 0;
3307:
3308: continue;
3309:
3310: }
3311:
3312: if (ch == CR) {
3313: xpos[io] = 0;
3314: continue;
3315: }
3316:
3317: if (ch == BS) {
3318: if (--xpos[io] < 0) xpos[io] = 0;
3319: continue;
3320: }
3321:
3322: if (ch == FF) {
3323:
3324: xpos[io] = 0;
3325: ypos[io] = 0;
3326:
3327: continue;
3328:
3329: }
3330:
3331: if (ch == TAB) {
3332: xpos[io] += 8 - (xpos[io] % 8);
3333: }
3334:
3335: } /* end while */
3336:
3337: tmp[i] = EOL;
3338:
3339: m_output (tmp);
3340:
3341: xpos[io] &= 0377;
3342: ypos[io] &= 0377;
3343:
3344: return;
3345:
3346: } /* end of write_m() */
3347:
3348: /* tab to number 'col' column' */
3349: void write_t (short int col)
3350: {
3351: short int i;
3352: short int j;
3353: char tmp[256]; /* Not tied to STRLEN necessarily*/
3354:
3355: if (col <= xpos[io]) return;
3356: if (col > (sizeof(tmp)-1)) col = (sizeof(tmp)-1); /* guard against buffer overflow */
3357:
3358: j = xpos[io];
3359: i = 0;
3360:
3361: while (j++ < col) tmp[i++] = SP;
3362:
3363: tmp[i] = EOL;
3364:
3365: write_m (tmp);
3366:
3367: return;
3368:
3369: } /* end of write_t() */
3370:
3371: void ontimo ()
3372: { /* handle timeout (for read) */
3373: longjmp (sjbuf, 1);
3374: } /* end of ontimo() */
3375:
3376: /* Try to read up to 'length' characters from current 'io'
3377: * If 'length' == zero a single character read is performed and
3378: * its $ASCII value is returned in 'stuff'.
3379: * A negative value of 'timeout' means there's no timeout.
3380: * a zero value looks whether a character has been typed in already
3381: * a positive value terminates the read after 'timeout' seconds
3382: * a timeout will set $TEST to TRUE if successfull, FALSE otherwise
3383: *
3384: * timeouts 1 .. 3 are done by polling,
3385: * higher timeouts request an alarm. that different treatment is
3386: * necessary, because timeouts may be up to 2 seconds early.
3387: * polling on higher timeouts would be require too much system resources
3388: * just for nothing.
3389: * maximum timeout is 32767 (2**15-1) seconds (about 9 hrs)
3390: * There are no provisions to handle overflow.
3391: */
3392: void read_m (char *stuff, long read_timeout, short read_timeoutms, short length)
3393: {
3394: static char previous[2][256] = {{EOL}, {EOL}}; /* all static: longjmp! */
3395: static short p_toggle = 0;
3396: static char term_key[256] = {EOL, EOL};
3397: static short int escptr;
3398: static short int single;
3399: static short int timoflag; /* timeout flag */
3400: static long int timex;
3401: static short int timexms;
3402: static short int i;
3403: static int ch;
3404:
3405: #ifdef USE_GETTIMEOFDAY
3406: static struct timeval timebuffer;
3407: #else
3408: static struct timeb timebuffer;
3409: #endif
3410:
3411: escptr = 0;
3412: single = 0;
3413: timoflag = FALSE;
3414:
3415: /* Not necessarily tied to STRLEN */
3416:
3417: if (length > 255) length = 255;
3418:
3419: stuff[length] = EOL;
3420: stuff[0] = EOL;
3421:
3422: if (length < 1) single = length = 1;
3423:
3424: timex = 0L;
3425: timexms = 0;
3426:
3427: if (io == HOME) opnfile[HOME] = stdin;
3428:
3429: if (io == HOME && !frm_filter) {
3430:
3431: if (NOTYPEAHEAD) fflush (stdin); /* ignore previous input */
3432:
3433: if (read_timeout >= 0) {
3434:
3435: test = TRUE;
3436:
3437: if (read_timeout > 2 && read_timeout <= 32767) { /* cave small/large values */
3438:
3439: if (setjmp (sjbuf)) {
3440:
3441: test = FALSE;
3442: timoflag = TRUE;
3443:
3444: goto done;
3445:
3446: }
3447:
3448: sig_attach (SIGALRM, &ontimo);
3449: alarm ((unsigned) read_timeout);
3450:
3451: read_timeout = (-1L);
3452:
3453: }
3454: else {
3455:
3456: if (read_timeout >= 0) {
3457:
3458:
3459: #ifdef USE_GETTIMEOFDAY
3460:
3461: gettimeofday (&timebuffer, NULL); /* get current time */
3462:
3463: read_timeout += timebuffer.tv_sec; /* target time */
3464: read_timeoutms += timebuffer.tv_usec;
3465:
3466: #else
3467:
3468: ftime (&timebuffer); /* get current time */
3469:
3470: read_timeout += timebuffer.time; /* target time */
3471: read_timeoutms += timebuffer.millitm;
3472:
3473: #endif
3474:
3475: if (read_timeoutms > 999) {
3476: read_timeoutms -= 1000;
3477: read_timeout++;
3478: }
3479:
3480: }
3481:
3482: }
3483:
3484: }
3485:
3486: zb[0] = EOL;
3487: zb[1] = EOL;
3488: zcc = FALSE;
3489:
3490: for (i = 0; i < length; i++) {
3491:
3492: if (merr () == INRPT) {
3493:
3494: if (--i < 0) i = 0;
3495: stuff[i] = EOL;
3496:
3497: break;
3498: }
3499:
3500: if (evt_async_enabled && (merr () == ASYNC)) break;
3501:
3502: /* TODO: remove old FreeM "journaling" nonsense here */
3503: if (jour_flag < 0) {
3504:
3505: if ((ch = fgetc (jouraccess)) == EOF) {
3506:
3507: jour_flag = 0;
3508:
3509: fclose (jouraccess);
3510:
3511: jouraccess = NULL;
3512:
3513: }
3514: else {
3515:
3516: if (ch == SI) {
3517: test = FALSE;
3518: break;
3519: } /* timeout char */
3520:
3521: }
3522:
3523: }
3524:
3525:
3526: if (jour_flag >= 0) {
3527:
3528: if (ug_buf[HOME][0] != EOL) {
3529: ch = ug_buf[HOME][0];
3530: stcpy (ug_buf[HOME], &ug_buf[HOME][1]);
3531: }
3532: else {
3533: if (read_timeout >= 0)
3534: #ifdef SYSFIVE
3535: {
3536: if (rdchk0 (&ch) == 1) {
3537: }
3538: #else
3539: {
3540:
3541: if (rdchk (fileno (stdin)) > 0)
3542: ch = getc (stdin);
3543: #endif /* SYSFIVE */
3544: else {
3545:
3546: if (read_timeout < 0) {
3547:
3548: test = FALSE;
3549: timoflag = TRUE;
3550: stuff[i] = EOL;
3551:
3552: break;
3553:
3554: }
3555: #ifdef USE_GETTIMEOFDAY
3556: gettimeofday (&timebuffer, NULL); /* get current time */
3557: if ((read_timeout < timebuffer.tv_sec) ||
3558: ((read_timeout == timebuffer.tv_sec) &&
3559: (read_timeoutms <= timebuffer.tv_usec))) {
3560: #else
3561: ftime (&timebuffer); /* get current time */
3562: if ((read_timeout < timebuffer.time) ||
3563: ((read_timeout == timebuffer.time) &&
3564: (read_timeoutms <= timebuffer.millitm))) {
3565: #endif
3566:
3567: test = FALSE;
3568: timoflag = TRUE;
3569: stuff[i] = EOL;
3570: break;
3571: }
3572:
3573: i--;
3574: continue;
3575:
3576: }
3577: }
3578: else {
3579: ch = getc (stdin);
3580: }
3581: }
3582: }
3583:
3584: if (UNSIGN (ch) == 255) {
3585: i--;
3586: continue;
3587: } /* illegal char */
3588:
3589: if (CONVUPPER) { /* convert to uppercase ? */
3590: if (ch >= 'a' && ch <= 'z') ch -= 32;
3591: }
3592:
3593: /* on CTRL/O suspend execution until next CTRL/O */
3594: if (ch == SI && CTRLOPROC) {
3595:
3596: printf ("\033[8p\033[4u"); /* screen dark, timeout off */
3597:
3598: while ((ch = getc (stdin)) != SI); /* loop until CTRL/O */
3599:
3600: printf ("\033[9p\033[5u"); /* screen light, timeout on */
3601:
3602: i--;
3603: continue;
3604: }
3605:
3606: zb[0] = ch;
3607:
3608: if (single == 0) {
3609:
3610: if (ch == ESC) {
3611:
3612: i--;
3613:
3614: term_key[0] = ESC;
3615: escptr = 1;
3616:
3617: continue;
3618:
3619: }
3620:
3621: if (escptr) {
3622:
3623: short j;
3624:
3625: i--;
3626:
3627: term_key[escptr++] = ch;
3628: term_key[escptr] = EOL;
3629:
3630: if (ch == '[' && escptr == 2) continue; /* CSI */
3631:
3632: /* DECs PF1..PF4 and Keypad application */
3633: if (ch == 'O' && PF1flag && escptr == 2) continue;
3634: if (escptr > 2 && (ch < '@' || ch >= DEL)) continue;
3635:
3636: if (ESCSEQPROC) {
3637: stcpy (zb, term_key);
3638: break;
3639: }
3640:
3641: if (escptr == 2) {
3642:
3643: if (ch == '9') { /* to begin of string */
3644:
3645: while (i >= 0) {
3646:
3647: if (ECHOON) {
3648:
3649: if (xpos[HOME] > 0) {
3650: write_m ("\033[D\201");
3651: }
3652: else {
3653: write_m ("\033M\033[79C\201");
3654: }
3655:
3656: }
3657:
3658: i--;
3659:
3660: }
3661:
3662: escptr = 0;
3663:
3664: continue;
3665:
3666: }
3667: else if (ch == ':') { /* to end of string */
3668:
3669: while (stuff[i] != EOL && stuff[i + 1] != EOL) {
3670:
3671: if (ECHOON) {
3672:
3673: if (xpos[HOME] < (n_columns - 1)) {
3674: write_m ("\033[C\201");
3675: }
3676: else {
3677: write_m ("\012\015\201");
3678: }
3679:
3680: }
3681:
3682: i++;
3683:
3684: }
3685:
3686: escptr = 0;
3687:
3688: continue;
3689:
3690: }
3691:
3692: }
3693:
3694: if (escptr == 3) {
3695:
3696: if (ch == 'D') { /* CUB left arrow */
3697:
3698: if (i >= 0) {
3699:
3700: if (ECHOON) {
3701:
3702: if (xpos[HOME] > 0) {
3703: write_m (term_key);
3704: }
3705: else {
3706: write_m ("\033M\033[79C\201");
3707: }
3708:
3709: }
3710:
3711: i--;
3712:
3713: }
3714:
3715: escptr = 0;
3716:
3717: continue;
3718:
3719: }
3720:
3721: if (stuff[i + 1] == EOL) {
3722: escptr = 0;
3723: continue;
3724: }
3725:
3726: if (ch == 'C') { /* CUF right arrow */
3727:
3728: if (ECHOON) {
3729:
3730: if (xpos[HOME] < (n_columns - 1)) {
3731: write_m (term_key);
3732: }
3733: else {
3734: write_m ("\012\015\201");
3735: }
3736:
3737: }
3738:
3739: i++;
3740:
3741: escptr = 0;
3742:
3743: continue;
3744:
3745: }
3746:
3747: if (ch == 'P') { /* DCH Delete Character */
3748:
3749: ch = i + 1;
3750:
3751: if (stuff[ch] != EOL) {
3752: while ((stuff[ch] = stuff[ch + 1]) != EOL) ch++;
3753: }
3754:
3755: if (ECHOON) {
3756:
3757: ch = xpos[HOME] + 1;
3758: j = ypos[HOME] + 1;
3759:
3760: stcpy (term_key, &stuff[i + 1]);
3761: stcat (term_key, " \033[\201");
3762: intstr (&term_key[stlen (term_key)], j);
3763: stcat (term_key, ";\201");
3764: intstr (&term_key[stlen (term_key)], ch);
3765: stcat (term_key, "H\201");
3766:
3767: write_m (term_key);
3768:
3769: }
3770:
3771: escptr = 0;
3772:
3773: continue;
3774:
3775: }
3776:
3777: if (ch == '@') { /* ICH Insert Character */
3778:
3779: ch = i;
3780: while (stuff[ch++] != EOL);
3781:
3782: while (ch > i) {
3783: stuff[ch] = stuff[ch - 1];
3784: ch--;
3785: }
3786:
3787: stuff[i + 1] = SP;
3788:
3789: if (ECHOON) {
3790:
3791: ch = xpos[HOME] + 1;
3792: j = ypos[HOME] + 1;
3793:
3794: stcpy (term_key, &stuff[i + 1]);
3795: stcat (term_key, "\033[\201");
3796: intstr (&term_key[stlen (term_key)], j);
3797: stcat (term_key, ";\201");
3798: intstr (&term_key[stlen (term_key)], ch);
3799: stcat (term_key, "H\201");
3800:
3801: write_m (term_key);
3802:
3803: }
3804:
3805: escptr = 0;
3806:
3807: continue;
3808:
3809: }
3810: }
3811:
3812: /* VT100 Functionkey */
3813: if (ch == '~' && (escptr == 4 || escptr == 5)) {
3814:
3815: j = term_key[2] - '0';
3816:
3817: if (term_key[3] != ch) j = j * 10 + term_key[3] - '0';
3818: if (j < 1 || j > 44) j = 0;
3819:
3820: }
3821: else {
3822: /* SCO Functionkey */
3823: j = find ("@ABCDFGHIJKLMNOP0_dTVX ;\"#$%&\'<=*+,-./123UWY\201", &term_key[1]);
3824: }
3825:
3826: escptr = 0;
3827:
3828: /* key unknown or without a value */
3829: if (j == 0 || zfunkey[j - 1][0] == EOL) continue;
3830:
3831: /* put key in input buffer, ignore overflow */
3832: {
3833: char tmp[256];
3834:
3835: stcpy (tmp, ug_buf[HOME]);
3836: stcpy (ug_buf[HOME], zfunkey[--j]);
3837: stcat (ug_buf[HOME], tmp);
3838: }
3839:
3840: continue;
3841: }
3842:
3843: term_key[0] = ch;
3844: term_key[1] = EOL;
3845:
3846: if (find (LineTerm, term_key)) break;
3847:
3848: if (ch == BS || ch == DEL) {
3849:
3850: if (stuff[i] != EOL) { /* DEL within string */
3851:
3852: if (ch == BS && i > 0) {
3853:
3854: if (ECHOON) {
3855:
3856: if (xpos[HOME] > 0) {
3857: write_m ("\033[D\201");
3858: }
3859: else {
3860: write_m ("\033M\033[79C\201");
3861: }
3862:
3863: }
3864:
3865: i--;
3866:
3867: }
3868:
3869: ch = i;
3870: if (stuff[ch] != EOL) {
3871: while ((stuff[ch] = stuff[ch + 1]) != EOL) ch++;
3872: }
3873:
3874: if (ECHOON) {
3875:
3876: int j;
3877:
3878: ch = xpos[HOME] + 1;
3879: j = ypos[HOME] + 1;
3880:
3881: stcpy (term_key, &stuff[i]);
3882: stcat (term_key, " \033[\201");
3883: intstr (&term_key[stlen (term_key)], j);
3884: stcat (term_key, ";\201");
3885: intstr (&term_key[stlen (term_key)], ch);
3886: stcat (term_key, "H\201");
3887:
3888: write_m (term_key);
3889:
3890: }
3891:
3892: continue;
3893:
3894: }
3895:
3896: if (i > 0) {
3897:
3898: if (ECHOON) {
3899:
3900: if (DELMODE) {
3901:
3902: if (xpos[HOME] > 0) {
3903: write_m ("\010 \010\201");
3904: }
3905: else {
3906: write_m ("\033M\033[79C\033[P\201");
3907: }
3908:
3909: } else {
3910: write_m ("\\\201");
3911: }
3912:
3913: }
3914:
3915: i--;
3916:
3917: ch = i;
3918:
3919: while ((stuff[ch] = stuff[ch + 1]) != EOL) ch++;
3920:
3921: }
3922: else if (DELEMPTY) {
3923:
3924: /* empty string delete? */
3925: stuff[0] = EOL;
3926: i = 1;
3927: term_key[0] = ch;
3928:
3929: break;
3930:
3931: }
3932:
3933: i--;
3934:
3935: continue;
3936:
3937: }
3938:
3939: if (ch == NAK || ch == DC2) { /* CTRL/U deletes all input */
3940:
3941: while (stuff[i] != EOL) {
3942:
3943: if (ECHOON) {
3944:
3945: if (xpos[HOME] < (n_columns - 1)) {
3946: write_m ("\033[C\201");
3947: }
3948: else {
3949: write_m ("\012\015\201");
3950: }
3951:
3952: }
3953:
3954: i++;
3955:
3956: }
3957:
3958: while (i > 0) {
3959:
3960: if (ECHOON) {
3961:
3962: if (DELMODE) {
3963:
3964: if (xpos[HOME] > 0) {
3965: write_m ("\010 \010\201");
3966: }
3967: else {
3968: write_m ("\033M\033[79C\033[P\201");
3969: }
3970:
3971: }
3972: else {
3973: write_m ("\\\201");
3974: }
3975:
3976: }
3977:
3978: stuff[i--] = EOL;
3979:
3980: }
3981:
3982: stuff[i--] = EOL;
3983:
3984: if (ch == NAK) continue;
3985:
3986: /* (ch==DC2) *//* CTRL/R Retypes last input */
3987:
3988: i = stcpy (stuff, previous[p_toggle]);
3989:
3990: stuff[i--] = EOL;
3991:
3992: toggle (p_toggle);
3993:
3994: if (ECHOON) write_m (stuff);
3995:
3996: continue;
3997: }
3998:
3999: if (ch == STX && (zbreakon || hardcopy)) {
4000:
4001: if (zbreakon) zbflag = TRUE;
4002:
4003: if (i > 0) {
4004: if (ECHOON) write_m ("\010 \010\201");
4005: }
4006:
4007: i--;
4008:
4009: continue;
4010:
4011: }
4012:
4013: if (ch == BrkKey) { /* CTRL/C may interrupt */
4014:
4015: i--;
4016:
4017: if (breakon) {
4018:
4019: stuff[i] = EOL;
4020: merr_raise (INRPT);
4021:
4022: return;
4023:
4024: }
4025:
4026: continue;
4027: }
4028:
4029: /* ignore non programmed CTRL/ key ?? */
4030: if (ch < SP && (ch != TAB || nstx) && NOCTRLS) { /* TAB may be a programmed key */
4031: i--;
4032: continue;
4033: }
4034:
4035: } /* if (single == 0) */
4036:
4037: if (stuff[i] == EOL) stuff[i + 1] = EOL;
4038: if (ch < 255) ch = (SIflag[io] ? G0I[io] : G1I[io])[UNSIGN (ch)];
4039:
4040: stuff[i] = ch;
4041:
4042: if (ECHOON) {
4043:
4044: term_key[0] = ch;
4045: term_key[1] = EOL;
4046:
4047: write_m (term_key);
4048:
4049: }
4050:
4051: } /* ??????????? may need to run through preprocessor to see where the heck this goes */
4052: }
4053: else { /* $io != HOME */
4054: int fd;
4055: int fdstat;
4056:
4057: fd = 0;
4058:
4059:
4060: #if defined(SYSFIVE) && !defined(__AMIGA) && !defined(MSDOS)
4061:
4062: if (read_timeout >= 0) {
4063:
4064: fd = fileno (opnfile[io]);
4065: fdstat = fcntl (fd, F_GETFL);
4066:
4067: fcntl (fd, F_SETFL, fdstat | O_NDELAY);
4068:
4069: }
4070:
4071: #endif /* SYSFIVE */
4072:
4073: for (i = 0; i < length; i++) {
4074:
4075: if (merr () == INRPT) {
4076:
4077: if (--i < 0) i = 0;
4078:
4079: stuff[i] = EOL;
4080:
4081: break;
4082:
4083: }
4084:
4085: if (ug_buf[io][0] != EOL) {
4086: ch = ug_buf[io][0];
4087: stcpy (ug_buf[io], &ug_buf[io][1]);
4088: }
4089: else if (read_timeout >= 0)
4090: {
4091: test = TRUE;
4092:
4093: #ifdef SYSFIVE
4094: if (fread (&ch, 1, 1, opnfile[io]) < 1)
4095: #else
4096: if (rdchk (fileno (opnfile[io])) == 0 || ((ch = fgetc (opnfile[io])) == EOF))
4097: #endif /* SYSFIVE */
4098:
4099: {
4100: if (--read_timeout < 0) {
4101:
4102: test = FALSE;
4103: timoflag = TRUE;
4104: stuff[i] = EOL;
4105:
4106: break;
4107:
4108: }
4109:
4110: sleep (1);
4111:
4112: i--;
4113:
4114: continue;
4115:
4116: }
4117:
4118: ch = UNSIGN (ch);
4119: }
4120: else {
4121: ch = fgetc (opnfile[io]);
4122: }
4123:
4124: stuff[i] = ch;
4125:
4126: if (ch == EOF) {
4127: /* EOF halts filtered mps */
4128: if ((io == HOME) && frm_filter) merr_raise (INRPT);
4129:
4130: stuff[i] = EOL;
4131:
4132: break;
4133: }
4134:
4135: if (single) break;
4136:
4137: if (ch == LF && crlf[io]) {
4138: i--;
4139: continue;
4140: }
4141:
4142: if ((ch == CR) || (ch == LF)) {
4143: int ch0;
4144:
4145: stuff[i] = EOL;
4146:
4147: /* if input terminates with CR/LF or LF/CR take both */
4148: /* as a single termination character. So it is possible */
4149: /* to get correct input from files written by mumps */
4150: /* itself with CR/LF line termination */
4151:
4152: #if defined(SYSFIVE) && !defined(__AMIGA) && !defined(MSDOS)
4153:
4154: if (fd == 0) {
4155:
4156: fd = fileno (opnfile[io]);
4157: fdstat = fcntl (fd, F_GETFL);
4158:
4159: fcntl (fd, F_SETFL, fdstat | O_NDELAY);
4160:
4161: }
4162:
4163: if (fread (&ch0, 1, 1, opnfile[io]) == 1) {
4164: ch0 = UNSIGN (ch0);
4165:
4166: #else
4167: #if !defined(__AMIGA) && !defined(MSDOS)
4168:
4169: if (rdchk (fileno (opnfile[io])) == 1) {
4170: ch0 = fgetc (opnfile[io]);
4171:
4172: #else
4173:
4174: #if defined(__AMIGA)
4175:
4176: if (rdchk0 (fileno (opnfile[io])) == 1) {
4177: ch0 = fgetc (opnfile[io]);
4178: #endif
4179:
4180: #endif /* __AMIGA */
4181:
4182: #if defined(MSDOS)
4183: if (1) {
4184: ch0 = fgetc (opnfile[io]);
4185: #endif
4186:
4187: #endif /* SYSFIVE */
4188:
4189: if ((ch == CR && ch0 != LF) || (ch == LF && ch0 != CR))
4190: ungetc (ch0, opnfile[io]);
4191: }
4192:
4193: break;
4194: }
4195:
4196: if (UNSIGN (stuff[i]) < 255)
4197: stuff[i] = (SIflag[io] ? G0I[io] : G1I[io])[UNSIGN (stuff[i])];
4198: }
4199:
4200: #if defined(SYSFIVE) && !defined(__AMIGA)
4201: if (fd) fcntl (fd, F_SETFL, fdstat);
4202: #endif /* SYSFIVE */
4203:
4204: } /* if ((ch == CR) || (ch == LF)) */
4205:
4206:
4207: done:
4208:
4209: alarm (0); /* reset alarm request */
4210:
4211: if (io == HOME && jour_flag > 0) {
4212:
4213: char tmp[256];
4214:
4215: tmp[stcpy (tmp, stuff)] = NUL;
4216: fputs (tmp, jouraccess);
4217:
4218: if (timoflag) {
4219:
4220: tmp[0] = SI;
4221: tmp[1] = NUL; /* CTRL/O as timeout char */
4222:
4223: fputs (tmp, jouraccess);
4224:
4225: }
4226: else if ((i < length) || (stuff[0] == NUL && zb[0] == ESC)) {
4227:
4228: /* save termination char if meaningful */
4229: tmp[stcpy (tmp, zb)] = NUL;
4230: fputs (tmp, jouraccess);
4231:
4232: }
4233:
4234: }
4235:
4236: if (single) { /* to ASCII */
4237:
4238: if (timoflag) {
4239: stuff[0] = '-';
4240: stuff[1] = '1';
4241: stuff[2] = EOL;
4242: }
4243: else {
4244: intstr (stuff, UNSIGN (stuff[0]));
4245: }
4246:
4247: }
4248: else if (io == HOME && stuff[0] != EOL) {
4249: stcpy (previous[toggle (p_toggle)], stuff);
4250: }
4251:
4252: return;
4253:
4254: } /* end of read_m() */
4255:
4256: #if defined(SYSFIVE)
4257: /* UNIX system V has no 'rdchk' function. We must do it ourselves */
4258:
4259: #if !defined(__AMIGA) && !defined(MSDOS)
4260:
4261: int rdchk0 (int *data)
4262: {
4263: static int x;
4264: static int firsttime = TRUE;
4265: int retcode;
4266: char ch;
4267:
4268: if (firsttime) {
4269: x = fcntl (0, F_GETFL);
4270: firsttime = FALSE;
4271: }
4272:
4273: fcntl (0, F_SETFL, x | O_NDELAY);
4274:
4275: retcode = read (0, &ch, 1);
4276:
4277: fcntl (0, F_SETFL, x);
4278:
4279: *data = (retcode > 0) ? ch : NUL;
4280:
4281: return retcode;
4282:
4283: } /* end rdchk0() */
4284:
4285: #else
4286:
4287: int rdchk0 (int *data)
4288: {
4289: /* TODO: flesh out on m68k-amigaos */
4290: return TRUE;
4291: }
4292:
4293: #endif
4294:
4295: /******************************************************************************/
4296: /* under XENIX the system has an intrinsic function 'locking'. */
4297: /* under UNIX System V it must be done with fcntl. */
4298: /* the difference is, that the XENIX locking blocks all other accesses */
4299: /* whereas UNIX System V gives only protection if all users of a file */
4300: /* use 'locking'. */
4301: /* since 'fcntl' is not properly documented, the outcome in any cases of */
4302: /* errors is uncertain. */
4303:
4304: #ifdef AMIGA68K
4305:
4306: int locking (int fd, int action, long count)
4307: {
4308: /* TODO: flesh out on m68k-amigaos */
4309: return 0;
4310: }
4311:
4312: #else
4313:
4314: /* fd = file descriptor of file to be locked */
4315: /* action = action to be performed */
4316: /* count area to be locked */
4317: int locking (int fd, int action, long count)
4318: {
4319:
4320: struct flock lock;
4321:
4322: lock.l_whence = 1; /* lock from current position */
4323: lock.l_start = 0;
4324: lock.l_len = count;
4325: lock.l_pid = getpid ();
4326:
4327: if (lonelyflag) return 0; /* no LOCK if single user */
4328:
4329: switch (action) {
4330:
4331:
4332: case 0: /* LK_UNLK free previously locked area */
4333:
4334: lock.l_type = F_UNLCK;
4335: fcntl (fd, F_SETLK, &lock);
4336:
4337: break;
4338:
4339:
4340: case 1: /* LK_LOCK lock against others reading and writing my data */
4341:
4342: lock.l_type = F_WRLCK;
4343: fcntl (fd, F_SETLKW, &lock);
4344:
4345: break;
4346:
4347:
4348: case 2: /* LK_NBLCK lock against others reading and writing my data, don't block */
4349:
4350: lock.l_type = F_WRLCK;
4351: fcntl (fd, F_SETLK, &lock);
4352:
4353: break;
4354:
4355:
4356: case 3: /* LK_RLCK lock against others writing my data */
4357:
4358: lock.l_type = F_RDLCK;
4359: fcntl (fd, F_SETLKW, &lock);
4360:
4361: break;
4362:
4363:
4364: case 4: /* LK_NBRLCK lock against others writing my data, don't block */
4365:
4366: lock.l_type = F_RDLCK;
4367: fcntl (fd, F_SETLK, &lock);
4368:
4369: break;
4370:
4371: }
4372:
4373: return 0; /* action properly performed */
4374:
4375: } /* end locking() */
4376:
4377: #endif
4378:
4379: #ifdef OLDUNIX
4380:
4381: /* set io_parameters to mumps/unix conventions */
4382: /* action: 0 = UNIX; 1 = MUMPS */
4383: void set_io (short action)
4384: {
4385: if (lio_mode == action) return;
4386:
4387: static char del;
4388: static char fs;
4389: struct termio tpara;
4390:
4391: if (frm_filter) return; /* nothing special if used as filter */
4392:
4393: fflush (stdin);
4394: fflush (stdout);
4395: fflush (stderr);
4396:
4397: ioctl (0, TCGETA, &tpara); /* get paramters */
4398:
4399: if (action == UNIX) {
4400:
4401: lio_mode = UNIX;
4402:
4403: tpara.c_lflag |= (ECHO | ICANON); /* enable echo/no cbreak mode */
4404: tpara.c_iflag |= ICRNL; /* cr-lf mapping */
4405: tpara.c_oflag |= ONLCR; /* cr-lf mapping */
4406: tpara.c_cc[VINTR] = del; /* interrupt */
4407: tpara.c_cc[VQUIT] = fs; /* quit */
4408: tpara.c_cc[VMIN] = EOT;
4409: tpara.c_cc[VTIME] = -1;
4410:
4411: }
4412: else { /* action == MUMPS */
4413:
4414: lio_mode = MUMPS;
4415:
4416: tpara.c_lflag &= (~(ECHO | ICANON)); /* disable echo/cbreak mode */
4417: tpara.c_iflag &= ~ICRNL; /* cr-lf mapping */
4418: tpara.c_oflag &= ~ONLCR; /* cr-lf mapping */
4419: del = tpara.c_cc[VINTR]; /* save previous state of */
4420: fs = tpara.c_cc[VQUIT]; /* quit and interrupt */
4421: tpara.c_cc[VINTR] = BrkKey; /* interrupt = CTRL/C */
4422: tpara.c_cc[VQUIT] = (zbreakon || hardcopy) ? STX : -1; /* zbreak/hardcopy */
4423: tpara.c_cc[VMIN] = 1;
4424: tpara.c_cc[VTIME] = 1;
4425:
4426: }
4427:
4428: ioctl (0, TCSETA, &tpara);
4429:
4430: return;
4431:
4432: } /* end of set_io() */
4433:
4434:
4435: /* break_char: */
4436: /* -1 = break disabled */
4437: /* ETX = MUMPS break */
4438: /* DEL = UNIX quit */
4439: void set_break (short break_char)
4440: {
4441: struct termio arg;
4442:
4443: ioctl (0, TCGETA, &arg);
4444:
4445: arg.c_cc[VINTR] = break_char; /* interrupt = CTRL/C */
4446:
4447: ioctl (0, TCSETA, &arg);
4448:
4449: return;
4450:
4451: } /* end of set_break() */
4452:
4453: /* quit_char: */
4454: /* -1 = quit disabled */
4455: /* STX = MUMPS CTRL/B */
4456: /* DEL = UNIX quit */
4457: void set_zbreak (short quit_char)
4458: {
4459: struct termio arg;
4460:
4461: ioctl (0, TCGETA, &arg);
4462:
4463: arg.c_cc[VQUIT] = quit_char;
4464:
4465: ioctl (0, TCSETA, &arg);
4466:
4467: return;
4468:
4469: } /* end of set_zbreak() */
4470:
4471: #else
4472:
4473: void set_io (short action) /* set io_parameters to mumps/unix conventions */
4474: {
4475: static struct termios unixtermio;
4476: struct termios termios_p;
4477:
4478: if (lio_mode == action) return;
4479:
4480: if (frm_filter) return; /* nothing special if used as filter */
4481:
4482: if (action == UNIX) {
4483: lio_mode = UNIX;
4484:
4485: tcsetattr (0, TCSADRAIN, &unixtermio);
4486: }
4487: else { /* action == MUMPS */
4488: lio_mode = MUMPS;
4489:
4490: tcgetattr (0, &unixtermio); /* get unix paramters */
4491: tcgetattr (0, &termios_p); /* get paramters */
4492:
4493: termios_p.c_lflag &= (~(ECHO | ICANON)); /* disable echo/cbreak mode */
4494: termios_p.c_iflag &= ~ICRNL; /* cr-lf mapping */
4495: termios_p.c_oflag &= ~ONLCR; /* cr-lf mapping */
4496: termios_p.c_cc[VINTR] = BrkKey; /* interrupt = CTRL/C */
4497: termios_p.c_cc[VQUIT] = (zbreakon || hardcopy) ? STX : -1; /* zbreak/hardcopy */
4498: termios_p.c_cc[VMIN] = 1;
4499: termios_p.c_cc[VTIME] = 1;
4500:
4501: tcsetattr (0, TCSADRAIN, &termios_p); /* set paramters */
4502:
4503: }
4504:
4505: return;
4506:
4507: } /* end of set_io() */
4508:
4509: void set_break (short break_char)
4510: {
4511: struct termios termios_p;
4512:
4513: tcgetattr (0, &termios_p);
4514:
4515: termios_p.c_cc[VINTR] = break_char; /* interrupt = CTRL/C */
4516:
4517: tcsetattr (0, TCSADRAIN, &termios_p); /* set paramters */
4518:
4519: return;
4520:
4521: } /* end of set_break() */
4522:
4523: void set_zbreak (short quit_char)
4524: {
4525:
4526: struct termios termios_p;
4527:
4528: tcgetattr (0, &termios_p);
4529:
4530: termios_p.c_cc[VQUIT] = quit_char;
4531:
4532: tcsetattr (0, TCSADRAIN, &termios_p); /* set paramters */
4533:
4534: return;
4535:
4536: } /* end of set_zbreak() */
4537:
4538: #endif /* OLDUNIX */
4539:
4540: #else
4541:
4542: /* same for XENIX */
4543: void set_io (short action) /* set io_parameters to mumps/unix conventions */
4544: {
4545: static char del;
4546: static char fs;
4547: struct sgttyb tt;
4548: struct tchars tc;
4549:
4550: if (frm_filter) return; /* nothing special if used as filter */
4551:
4552: fflush (stdin);
4553: fflush (stdout);
4554: fflush (stderr);
4555:
4556: ioctl (0, TIOCGETP, &tt);
4557: ioctl (0, TIOCGETC, &tc);
4558:
4559: if (action == UNIX) {
4560:
4561: tt.sg_flags &= ~02; /* no cbreak mode */
4562: tt.sg_flags |= (010 | 020); /* echo ; CR to LF map */
4563: tc.t_quitc = fs; /* quit */
4564: tc.t_intrc = del; /* interrupt */
4565:
4566: /* we desperately tried to do it with DEL - but it didn't work */
4567:
4568: }
4569: else { /* action == MUMPS */
4570:
4571: tt.sg_flags |= 02; /* cbreak mode */
4572: tt.sg_flags &= (~010 & ~020); /* 10 no echo; 20 no CR map */
4573: del = tc.t_intrc; /* save previous state of */
4574: fs = tc.t_quitc; /* quit and interrupt */
4575: tc.t_intrc = BrkKey; /* interrupt = CTRL/C */
4576: tc.t_quitc = (zbreakon || hardcopy) ? STX : -1; /* zbreak/hardcopy */
4577:
4578: }
4579:
4580: ioctl (0, TIOCSETP, &tt);
4581: ioctl (0, TIOCSETC, &tc);
4582:
4583: } /* end of set_io() */
4584:
4585: void set_break (short break_char)
4586: {
4587: struct tchars tc;
4588:
4589: ioctl (0, TIOCGETC, &tc);
4590:
4591: tc.t_intrc = break_char;
4592:
4593: ioctl (0, TIOCSETC, &tc);
4594:
4595: return;
4596:
4597: } /* end of set_break */
4598:
4599: void set_zbreak (short quit_char)
4600: {
4601: struct tchars tc;
4602:
4603:
4604: ioctl (0, TIOCGETC, &tc);
4605:
4606: tc.t_quitc = quit_char;
4607:
4608: ioctl (0, TIOCSETC, &tc);
4609:
4610: return;
4611:
4612: } /* end of set_zbreak */
4613:
4614: #endif /* SYSFIVE */
4615:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>