|
|
1.1 root 1: #include "mint.h"
2:
3: #include "fasttext.h"
4:
5:
6:
7: #ifdef FASTTEXT
8:
9:
10:
11: #ifdef __GNUC__
12:
13: #define INLINE inline
14:
15: #define ITYPE long /* gcc's optimizer likes 32 bit integers */
16:
17: #else
18:
19: #define INLINE
20:
21: #define ITYPE int
22:
23: #endif
24:
25:
26:
27: #define CONDEV (2)
28:
29:
30:
31: static SCREEN *current;
32:
33:
34:
35: static void paint P_((SCREEN *, int, char *)),
36:
37: paint8c P_((SCREEN *, int, char *)),
38:
39: paint16m P_((SCREEN *, int, char *));
40:
41:
42:
43: INLINE static void curs_off P_((SCREEN *)), curs_on P_((SCREEN *));
44:
45: INLINE static void flash P_((SCREEN *));
46:
47: static void normal_putch P_((SCREEN *, int));
48:
49: static void escy_putch P_((SCREEN *, int));
50:
51:
52:
53: static char *chartab[256];
54:
55:
56:
57: static long scrnsize;
58:
59:
60:
61: short hardscroll;
62:
63: static char *hardbase, *oldbase;
64:
65:
66:
67: typedef void (*Vfunc) P_((SCREEN *, int));
68:
69:
70:
71: #define base *((char **)0x44eL)
72:
73: #define escy1 *((short *)0x4acL)
74:
75:
76:
77: static Vfunc state;
78:
79:
80:
81: static short hardline;
82:
83: static void (*vpaint) P_((SCREEN *, int, char *));
84:
85:
86:
87: void init P_((void));
88:
89: void hardware_scroll P_((SCREEN *));
90:
91: INLINE static char *PLACE P_((SCREEN *, int, int));
92:
93: INLINE static void gotoxy P_((SCREEN *, int, int));
94:
95: INLINE static void clrline P_((SCREEN *, int));
96:
97: INLINE static void clear P_((SCREEN *));
98:
99: INLINE static void clrchar P_((SCREEN *, int, int));
100:
101: INLINE static void clrfrom P_((SCREEN *, int, int, int, int));
102:
103: INLINE static void delete_line P_((SCREEN *, int));
104:
105: INLINE static void insert_line P_((SCREEN *, int));
106:
107: static void setbgcol P_((SCREEN *, int));
108:
109: static void setfgcol P_((SCREEN *, int));
110:
111: static void putesc P_((SCREEN *, int));
112:
113: static void escy1_putch P_((SCREEN *, int));
114:
115: INLINE static void put_ch P_((SCREEN *, int));
116:
117:
118:
119: /* routines for flashing the cursor for screen v */
120:
121: /* flash(v): invert the character currently under the cursor */
122:
123:
124:
125: INLINE static void
126:
127: flash(v)
128:
129: SCREEN *v;
130:
131: {
132:
133: char *place, d;
134:
135: ITYPE i, j, vplanes;
136:
137:
138:
139: vplanes = v->planes + v->planes;
140:
141: place = v->cursaddr;
142:
143:
144:
145: for (j = v->cheight; j > 0; --j) {
146:
147: d = (*place) ^ 0xff;
148:
149: for (i = 0; i < vplanes; i+=2)
150:
151: place[i] = d;
152:
153:
154:
155: place += v->planesiz;
156:
157: }
158:
159: }
160:
161:
162:
163: /* make sure the cursor is off */
164:
165:
166:
167: INLINE
168:
169: static void
170:
171: curs_off(v)
172:
173: SCREEN *v;
174:
175: {
176:
177: if (v->flags & CURS_ON) {
178:
179: if (v->flags & CURS_FSTATE) {
180:
181: flash(v);
182:
183: v->flags &= ~CURS_FSTATE;
184:
185: }
186:
187: }
188:
189: }
190:
191:
192:
193: /* OK, show the cursor again (if appropriate) */
194:
195:
196:
197: INLINE static void
198:
199: curs_on(v)
200:
201: SCREEN *v;
202:
203: {
204:
205: if (v->hidecnt) return;
206:
207:
208:
209: if (v->flags & CURS_ON) {
210:
211: /* if the cursor is flashing, we cheat a little and leave it off
212:
213: * to be turned on again (if necessary) by the VBL routine
214:
215: */
216:
217: if (v->flags & CURS_FLASH) {
218:
219: v->curstimer = 2;
220:
221: return;
222:
223: }
224:
225: if (!(v->flags & CURS_FSTATE)) {
226:
227: v->flags |= CURS_FSTATE;
228:
229: flash(v);
230:
231: }
232:
233: }
234:
235: }
236:
237:
238:
239: void
240:
241: init()
242:
243: {
244:
245: SCREEN *v;
246:
247: int i, j;
248:
249: char *data, *foo;
250:
251: static char chardata[256*16];
252:
253:
254:
255: foo = lineA0();
256:
257: v = (SCREEN *)(foo - 346);
258:
259:
260:
261: /* Ehem... The screen might be bigger than 32767 bytes.
262:
263: Let's do some casting...
264:
265: Erling
266:
267: */
268:
269: scrnsize = (v->maxy+1)*(long)v->linelen;
270:
271: if (hardscroll > 0) {
272:
273: if (!hardbase)
274:
275: hardbase = (char *)(((long)kcore(SCNSIZE(v)+256L)+255L)
276:
277: & 0xffffff00L);
278:
279:
280:
281: if (hardbase == 0) {
282:
283: ALERT("Insufficient memory for hardware scrolling!");
284:
285: } else {
286:
287: quickmove(hardbase, base, scrnsize);
288:
289: v->cursaddr = v->cursaddr + (hardbase - base);
290:
291: oldbase = base;
292:
293: base = hardbase;
294:
295: Setscreen(hardbase, hardbase, -1);
296:
297: }
298:
299: }
300:
301: hardline = 0;
302:
303: if (v->cheight == 8 && v->planes == 2) {
304:
305: foo = &chardata[0];
306:
307: vpaint = paint8c;
308:
309: for (i = 0; i < 256; i++) {
310:
311: chartab[i] = foo;
312:
313: data = v->fontdata + i;
314:
315: for (j = 0; j < 8; j++) {
316:
317: *foo++ = *data;
318:
319: data += v->form_width;
320:
321: }
322:
323: }
324:
325: } else if (v->cheight == 16 && v->planes == 1) {
326:
327: foo = &chardata[0];
328:
329: vpaint = paint16m;
330:
331: for (i = 0; i < 256; i++) {
332:
333: chartab[i] = foo;
334:
335: data = v->fontdata + i;
336:
337: for (j = 0; j < 16; j++) {
338:
339: *foo++ = *data;
340:
341: data += v->form_width;
342:
343: }
344:
345: }
346:
347: }
348:
349: else
350:
351: vpaint = paint;
352:
353:
354:
355: if (v->hidecnt == 0) {
356:
357: /*
358:
359: * make sure the cursor is set up correctly and turned on
360:
361: */
362:
363: (void)Cursconf(0,0); /* turn cursor off */
364:
365:
366:
367: v->flags &= ~(CURS_FLASH|CURS_FSTATE);
368:
369:
370:
371: /* now turn the cursor on the way we like it */
372:
373: v->hidecnt = 0;
374:
375: curs_on(v);
376:
377: } else {
378:
379: (void)Cursconf(0,0);
380:
381: v->flags &= ~CURS_ON;
382:
383: v->hidecnt = 1;
384:
385: }
386:
387:
388:
389: current = v;
390:
391: state = normal_putch;
392:
393: }
394:
395:
396:
397: /*
398:
399: * PLACE(v, x, y): the address corresponding to the upper left hand corner of
400:
401: * the character at position (x,y) on screen v
402:
403: */
404:
405: INLINE static
406:
407: char *PLACE(v, x, y)
408:
409: SCREEN *v;
410:
411: int x, y;
412:
413: {
414:
415: char *place;
416:
417: int i, j;
418:
419:
420:
421: place = base + x;
422:
423: if (y == v->maxy)
424:
425: place += scrnsize - v->linelen;
426:
427: else if (y) /* Yo, the screen might be bigger than 32767 bytes...
428:
429: Do a cast to long. Erling. */
430:
431: place += (long)y * v->linelen;
432:
433:
434:
435: if ((j = v->planes) > 1) {
436:
437: i = (x & 0xfffe);
438:
439: while (--j > 0)
440:
441: place += i;
442:
443: }
444:
445: return place;
446:
447: }
448:
449:
450:
451: /*
452:
453: * paint(v, c, place): put character 'c' at position 'place' on screen
454:
455: * v. It is assumed that x, y are proper coordinates!
456:
457: * Specialized versions (paint8c and paint16m) of this routine follow;
458:
459: * they assume 8 line high characters, medium res. and 16 line/mono,
460:
461: * respectively.
462:
463: */
464:
465:
466:
467: static void
468:
469: paint(v, c, place)
470:
471: SCREEN *v;
472:
473: int c;
474:
475: char *place;
476:
477: {
478:
479: char *data, d, doinverse;
480:
481: ITYPE j, planecount;
482:
483: int vplanes;
484:
485: long vform_width, vplanesiz;
486:
487:
488:
489: vplanes = v->planes;
490:
491:
492:
493: data = v->fontdata + c;
494:
495: doinverse = (v->flags & FINVERSE) ? 0xff : 0;
496:
497: vform_width = v->form_width;
498:
499: vplanesiz = v->planesiz;
500:
501:
502:
503: for (j = v->cheight; j > 0; --j) {
504:
505: d = *data ^ doinverse;
506:
507: *place = d;
508:
509: if (vplanes > 1) {
510:
511: /* This should work for an arbitrary number of planes. Erling */
512:
513: for(planecount=1;planecount<vplanes;planecount++)
514:
515: place[(planecount<<1)]=d;
516:
517: #if 0
518:
519: {
520:
521: place[2] = d;
522:
523: if (vplanes > 2) {
524:
525: place[4] = place[6] = d;
526:
527: }
528:
529: }
530:
531: #endif
532:
533: }
534:
535:
536:
537: place += vplanesiz;
538:
539: data += vform_width;
540:
541: }
542:
543:
544:
545: }
546:
547:
548:
549: static void
550:
551: paint8c(v, c, place)
552:
553: SCREEN *v;
554:
555: int c;
556:
557: char *place;
558:
559: {
560:
561: char *data;
562:
563: char d, doinverse;
564:
565: long vplanesiz;
566:
567:
568:
569: data = chartab[c];
570:
571:
572:
573: doinverse = (v->flags & FINVERSE) ? 0xff : 0;
574:
575: vplanesiz = v->planesiz;
576:
577:
578:
579: if (!doinverse) {
580:
581: /* line 1 */
582:
583: d = *data++;
584:
585: *place = d;
586:
587: place[2] = d;
588:
589: place += vplanesiz;
590:
591:
592:
593: /* line 2 */
594:
595: d = *data++;
596:
597: *place = d;
598:
599: place[2] = d;
600:
601: place += vplanesiz;
602:
603:
604:
605: /* line 3 */
606:
607: d = *data++;
608:
609: *place = d;
610:
611: place[2] = d;
612:
613: place += vplanesiz;
614:
615:
616:
617: /* line 4 */
618:
619: d = *data++;
620:
621: *place = d;
622:
623: place[2] = d;
624:
625: place += vplanesiz;
626:
627:
628:
629: /* line 5 */
630:
631: d = *data++;
632:
633: *place = d;
634:
635: place[2] = d;
636:
637: place += vplanesiz;
638:
639:
640:
641: /* line 6 */
642:
643: d = *data++;
644:
645: *place = d;
646:
647: place[2] = d;
648:
649: place += vplanesiz;
650:
651:
652:
653: /* line 7 */
654:
655: d = *data++;
656:
657: *place = d;
658:
659: place[2] = d;
660:
661: place += vplanesiz;
662:
663:
664:
665: /* line 8 */
666:
667: d = *data++;
668:
669: *place = d;
670:
671: place[2] = d;
672:
673: place += vplanesiz;
674:
675: } else {
676:
677: /* line 1 */
678:
679: d = *data++ ^ doinverse;
680:
681: *place = d;
682:
683: place[2] = d;
684:
685: place += vplanesiz;
686:
687:
688:
689: /* line 2 */
690:
691: d = *data++ ^ doinverse;
692:
693: *place = d;
694:
695: place[2] = d;
696:
697: place += vplanesiz;
698:
699:
700:
701: /* line 3 */
702:
703: d = *data++ ^ doinverse;
704:
705: *place = d;
706:
707: place[2] = d;
708:
709: place += vplanesiz;
710:
711:
712:
713: /* line 4 */
714:
715: d = *data++ ^ doinverse;
716:
717: *place = d;
718:
719: place[2] = d;
720:
721: place += vplanesiz;
722:
723:
724:
725: /* line 5 */
726:
727: d = *data++ ^ doinverse;
728:
729: *place = d;
730:
731: place[2] = d;
732:
733: place += vplanesiz;
734:
735:
736:
737: /* line 6 */
738:
739: d = *data++ ^ doinverse;
740:
741: *place = d;
742:
743: place[2] = d;
744:
745: place += vplanesiz;
746:
747:
748:
749: /* line 7 */
750:
751: d = *data++ ^ doinverse;
752:
753: *place = d;
754:
755: place[2] = d;
756:
757: place += vplanesiz;
758:
759:
760:
761: /* line 8 */
762:
763: d = *data++ ^ doinverse;
764:
765: *place = d;
766:
767: place[2] = d;
768:
769: place += vplanesiz;
770:
771: }
772:
773: }
774:
775:
776:
777: static void
778:
779: paint16m(v, c, place)
780:
781: SCREEN *v;
782:
783: int c;
784:
785: char *place;
786:
787: {
788:
789: char *data;
790:
791: char d, doinverse;
792:
793: long vplanesiz;
794:
795:
796:
797: data = chartab[c];
798:
799: doinverse = (v->flags & FINVERSE) ? 0xff : 0;
800:
801: vplanesiz = v->planesiz;
802:
803:
804:
805: if (!doinverse) {
806:
807: /* line 1 */
808:
809: d = *data++;
810:
811: *place = d;
812:
813: place += vplanesiz;
814:
815:
816:
817: /* line 2 */
818:
819: d = *data++;
820:
821: *place = d;
822:
823: place += vplanesiz;
824:
825:
826:
827: /* line 3 */
828:
829: d = *data++;
830:
831: *place = d;
832:
833: place += vplanesiz;
834:
835:
836:
837: /* line 4 */
838:
839: d = *data++;
840:
841: *place = d;
842:
843: place += vplanesiz;
844:
845:
846:
847: /* line 5 */
848:
849: d = *data++;
850:
851: *place = d;
852:
853: place += vplanesiz;
854:
855:
856:
857: /* line 6 */
858:
859: d = *data++;
860:
861: *place = d;
862:
863: place += vplanesiz;
864:
865:
866:
867: /* line 7 */
868:
869: d = *data++;
870:
871: *place = d;
872:
873: place += vplanesiz;
874:
875:
876:
877: /* line 8 */
878:
879: d = *data++;
880:
881: *place = d;
882:
883: place += vplanesiz;
884:
885:
886:
887: /* line 9 */
888:
889: d = *data++;
890:
891: *place = d;
892:
893: place += vplanesiz;
894:
895:
896:
897: /* line 10 */
898:
899: d = *data++;
900:
901: *place = d;
902:
903: place += vplanesiz;
904:
905:
906:
907: /* line 11 */
908:
909: d = *data++;
910:
911: *place = d;
912:
913: place += vplanesiz;
914:
915:
916:
917: /* line 12 */
918:
919: d = *data++;
920:
921: *place = d;
922:
923: place += vplanesiz;
924:
925:
926:
927: /* line 13 */
928:
929: d = *data++;
930:
931: *place = d;
932:
933: place += vplanesiz;
934:
935:
936:
937: /* line 14 */
938:
939: d = *data++;
940:
941: *place = d;
942:
943: place += vplanesiz;
944:
945:
946:
947: /* line 15 */
948:
949: d = *data++;
950:
951: *place = d;
952:
953: place += vplanesiz;
954:
955:
956:
957: /* line 16 */
958:
959: d = *data++;
960:
961: *place = d;
962:
963: place += vplanesiz;
964:
965: } else {
966:
967: /* line 1 */
968:
969: d = *data++ ^ doinverse;
970:
971: *place = d;
972:
973: place += vplanesiz;
974:
975:
976:
977: /* line 2 */
978:
979: d = *data++ ^ doinverse;
980:
981: *place = d;
982:
983: place += vplanesiz;
984:
985:
986:
987: /* line 3 */
988:
989: d = *data++ ^ doinverse;
990:
991: *place = d;
992:
993: place += vplanesiz;
994:
995:
996:
997: /* line 4 */
998:
999: d = *data++ ^ doinverse;
1000:
1001: *place = d;
1002:
1003: place += vplanesiz;
1004:
1005:
1006:
1007: /* line 5 */
1008:
1009: d = *data++ ^ doinverse;
1010:
1011: *place = d;
1012:
1013: place += vplanesiz;
1014:
1015:
1016:
1017: /* line 6 */
1018:
1019: d = *data++ ^ doinverse;
1020:
1021: *place = d;
1022:
1023: place += vplanesiz;
1024:
1025:
1026:
1027: /* line 7 */
1028:
1029: d = *data++ ^ doinverse;
1030:
1031: *place = d;
1032:
1033: place += vplanesiz;
1034:
1035:
1036:
1037: /* line 8 */
1038:
1039: d = *data++ ^ doinverse;
1040:
1041: *place = d;
1042:
1043: place += vplanesiz;
1044:
1045:
1046:
1047: /* line 9 */
1048:
1049: d = *data++ ^ doinverse;
1050:
1051: *place = d;
1052:
1053: place += vplanesiz;
1054:
1055:
1056:
1057: /* line 10 */
1058:
1059: d = *data++ ^ doinverse;
1060:
1061: *place = d;
1062:
1063: place += vplanesiz;
1064:
1065:
1066:
1067: /* line 11 */
1068:
1069: d = *data++ ^ doinverse;
1070:
1071: *place = d;
1072:
1073: place += vplanesiz;
1074:
1075:
1076:
1077: /* line 12 */
1078:
1079: d = *data++ ^ doinverse;
1080:
1081: *place = d;
1082:
1083: place += vplanesiz;
1084:
1085:
1086:
1087: /* line 13 */
1088:
1089: d = *data++ ^ doinverse;
1090:
1091: *place = d;
1092:
1093: place += vplanesiz;
1094:
1095:
1096:
1097: /* line 14 */
1098:
1099: d = *data++ ^ doinverse;
1100:
1101: *place = d;
1102:
1103: place += vplanesiz;
1104:
1105:
1106:
1107: /* line 15 */
1108:
1109: d = *data++ ^ doinverse;
1110:
1111: *place = d;
1112:
1113: place += vplanesiz;
1114:
1115:
1116:
1117: /* line 16 */
1118:
1119: d = *data++ ^ doinverse;
1120:
1121: *place = d;
1122:
1123: place += vplanesiz;
1124:
1125: }
1126:
1127: }
1128:
1129:
1130:
1131: /*
1132:
1133: * gotoxy (v, x, y): move current cursor address of screen v to (x, y)
1134:
1135: * makes sure that (x, y) will be legal
1136:
1137: */
1138:
1139:
1140:
1141: INLINE static void
1142:
1143: gotoxy(v, x, y)
1144:
1145: SCREEN *v;
1146:
1147: int x, y;
1148:
1149: {
1150:
1151: if (x > v->maxx) x = v->maxx;
1152:
1153: else if (x < 0) x = 0;
1154:
1155: if (y > v->maxy) y = v->maxy;
1156:
1157: else if (y < 0) y = 0;
1158:
1159: curs_off(v);
1160:
1161:
1162:
1163: v->cx = x;
1164:
1165: v->cy = y;
1166:
1167: v->cursaddr = PLACE(v, x, y);
1168:
1169: }
1170:
1171:
1172:
1173: /*
1174:
1175: * clrline(v, r): clear line r of screen v
1176:
1177: */
1178:
1179:
1180:
1181: INLINE static void
1182:
1183: clrline(v, r)
1184:
1185: SCREEN *v;
1186:
1187: int r;
1188:
1189: {
1190:
1191: long *dst;
1192:
1193: long nbytes;
1194:
1195:
1196:
1197: nbytes = v->linelen;
1198:
1199: /* Hey, again the screen might be bigger than 32767 bytes.
1200:
1201: Do another cast... */
1202:
1203: dst = (long *)(base + ((long)r * v->linelen));
1204:
1205: zero((char *)dst, nbytes);
1206:
1207: }
1208:
1209:
1210:
1211: /*
1212:
1213: * clear(v): clear the whole screen v
1214:
1215: */
1216:
1217:
1218:
1219: INLINE static void
1220:
1221: clear(v)
1222:
1223: SCREEN *v;
1224:
1225: {
1226:
1227: zero(base, scrnsize);
1228:
1229: }
1230:
1231:
1232:
1233: /*
1234:
1235: * clrchar(v, x, y): clear the (x,y) position on screen v
1236:
1237: */
1238:
1239:
1240:
1241: INLINE static void
1242:
1243: clrchar(v, x, y)
1244:
1245: SCREEN *v;
1246:
1247: int x, y;
1248:
1249: {
1250:
1251: int i, j, vplanes;
1252:
1253: char *place;
1254:
1255:
1256:
1257: vplanes = v->planes + v->planes;
1258:
1259:
1260:
1261: place = PLACE(v, x, y);
1262:
1263:
1264:
1265: for (j = v->cheight; j > 0; --j) {
1266:
1267: for (i = 0; i < vplanes; i+=2)
1268:
1269: place[i] = 0;
1270:
1271: place += v->planesiz;
1272:
1273: }
1274:
1275: }
1276:
1277:
1278:
1279: /*
1280:
1281: * clrfrom(v, x1, y1, x2, y2): clear screen v from position (x1,y1) to
1282:
1283: * position (x2, y2) inclusive. It is assumed that y2 >= y1.
1284:
1285: */
1286:
1287:
1288:
1289: INLINE static void
1290:
1291: clrfrom(v, x1, y1, x2, y2)
1292:
1293: SCREEN *v;
1294:
1295: int x1,y1,x2,y2;
1296:
1297: {
1298:
1299: int i;
1300:
1301:
1302:
1303: for (i = x1; i <= v->maxx; i++)
1304:
1305: clrchar(v, i, y1);
1306:
1307: if (y2 > y1) {
1308:
1309: for (i = 0; i <= x2; i++)
1310:
1311: clrchar(v, i, y2);
1312:
1313: for (i = y1+1; i < y2; i++)
1314:
1315: clrline(v, i);
1316:
1317: }
1318:
1319: }
1320:
1321:
1322:
1323: /*
1324:
1325: * scroll a screen in hardware; if we still have hardware scrolling lines left,
1326:
1327: * just move the physical screen base, otherwise copy the screen back to the
1328:
1329: * hardware base and start over
1330:
1331: */
1332:
1333: void
1334:
1335: hardware_scroll(v)
1336:
1337: SCREEN *v;
1338:
1339: {
1340:
1341:
1342:
1343: ++hardline;
1344:
1345: if (hardline < hardscroll) { /* just move the screen */
1346:
1347: base += v->linelen;
1348:
1349: v->cursaddr = PLACE(v, v->cx, v->cy);
1350:
1351: Setscreen(base, base, -1);
1352:
1353: }
1354:
1355: else {
1356:
1357: hardline = 0;
1358:
1359: quickmove(hardbase, base + v->linelen, scrnsize - v->linelen);
1360:
1361: base = hardbase;
1362:
1363: v->cursaddr = PLACE(v, v->cx, v->cy);
1364:
1365: Setscreen(hardbase, hardbase, -1);
1366:
1367: }
1368:
1369: }
1370:
1371:
1372:
1373: /*
1374:
1375: * delete_line(v, r): delete line r of screen v. The screen below this
1376:
1377: * line is scrolled up, and the bottom line is cleared.
1378:
1379: */
1380:
1381:
1382:
1383: #define scroll(v) delete_line(v, 0)
1384:
1385:
1386:
1387: INLINE static void
1388:
1389: delete_line(v, r)
1390:
1391: SCREEN *v;
1392:
1393: int r;
1394:
1395: {
1396:
1397: long *src, *dst, nbytes;
1398:
1399:
1400:
1401: if (r == 0) {
1402:
1403: if (hardbase) {
1404:
1405: hardware_scroll(v);
1406:
1407: clrline(v, v->maxy);
1408:
1409: return;
1410:
1411: }
1412:
1413: nbytes = scrnsize - v->linelen;
1414:
1415: }
1416:
1417: else
1418:
1419: nbytes = (long)v->linelen * (v->maxy - r);
1420:
1421:
1422:
1423: /* Sheeze, how many times do we really have to cast...
1424:
1425: Erling.
1426:
1427: */
1428:
1429:
1430:
1431: dst = (long *)(base + ((long)r * v->linelen));
1432:
1433: src = (long *)( ((long)dst) + v->linelen);
1434:
1435:
1436:
1437: quickmove(dst, src, nbytes);
1438:
1439:
1440:
1441: /* clear the last line */
1442:
1443: clrline(v, v->maxy);
1444:
1445: }
1446:
1447:
1448:
1449: /*
1450:
1451: * insert_line(v, r): scroll all of the screen starting at line r down,
1452:
1453: * and then clear line r.
1454:
1455: */
1456:
1457:
1458:
1459: INLINE static void
1460:
1461: insert_line(v, r)
1462:
1463: SCREEN *v;
1464:
1465: int r;
1466:
1467: {
1468:
1469: long *src, *dst;
1470:
1471: int i, limit;
1472:
1473:
1474:
1475: limit = v->maxy;
1476:
1477: for (i = limit-1; i >= r ; --i) {
1478:
1479: /* move line i to line i+1 */
1480:
1481: /* AND do some casting to support big screens.
1482:
1483: Erling
1484:
1485: */
1486:
1487: src = (long *)(base + ((long)i * v->linelen));
1488:
1489: dst = (long *)(base + ((i+1)*(long)v->linelen));
1490:
1491: quickmove(dst, src, v->linelen);
1492:
1493: }
1494:
1495:
1496:
1497: /* clear line r */
1498:
1499: clrline(v, r);
1500:
1501: }
1502:
1503:
1504:
1505: /*
1506:
1507: * special states for handling ESC b x and ESC c x. Note that for now,
1508:
1509: * color is ignored.
1510:
1511: */
1512:
1513:
1514:
1515: static void
1516:
1517: setbgcol(v, c)
1518:
1519: SCREEN *v;
1520:
1521: int c;
1522:
1523: {
1524:
1525: v->bgcol = c & ((1 << v->planes)-1);
1526:
1527: state = normal_putch;
1528:
1529: }
1530:
1531:
1532:
1533: static void
1534:
1535: setfgcol(v, c)
1536:
1537: SCREEN *v;
1538:
1539: int c;
1540:
1541: {
1542:
1543: v->fgcol = c & ((1 << v->planes)-1);
1544:
1545: state = normal_putch;
1546:
1547: }
1548:
1549:
1550:
1551: /*
1552:
1553: * putesc(v, c): handle the control sequence ESC c
1554:
1555: */
1556:
1557:
1558:
1559: static void
1560:
1561: putesc(v, c)
1562:
1563: SCREEN *v;
1564:
1565: int c;
1566:
1567: {
1568:
1569: int cx, cy;
1570:
1571:
1572:
1573: cx = v->cx; cy = v->cy;
1574:
1575:
1576:
1577: switch (c) {
1578:
1579: case 'A': /* cursor up */
1580:
1581: gotoxy(v, cx, cy-1);
1582:
1583: break;
1584:
1585: case 'B': /* cursor down */
1586:
1587: gotoxy(v, cx, cy+1);
1588:
1589: break;
1590:
1591: case 'C': /* cursor right */
1592:
1593: gotoxy(v, cx+1, cy);
1594:
1595: break;
1596:
1597: case 'D': /* cursor left */
1598:
1599: gotoxy(v, cx-1, cy);
1600:
1601: break;
1602:
1603: case 'E': /* clear home */
1604:
1605: curs_off(v);
1606:
1607: clear(v);
1608:
1609: /* fall through... */
1610:
1611: case 'H': /* cursor home */
1612:
1613: gotoxy(v, 0, 0);
1614:
1615: break;
1616:
1617: case 'I': /* cursor up, insert line */
1618:
1619: if (cy == 0) {
1620:
1621: curs_off(v);
1622:
1623: insert_line(v, 0);
1624:
1625: }
1626:
1627: else
1628:
1629: gotoxy(v, cx, cy-1);
1630:
1631: break;
1632:
1633: case 'J': /* clear below cursor */
1634:
1635: curs_off(v);
1636:
1637: clrfrom(v, cx, cy, v->maxx, v->maxy);
1638:
1639: break;
1640:
1641: case 'K': /* clear remainder of line */
1642:
1643: curs_off(v);
1644:
1645: clrfrom(v, cx, cy, v->maxx, cy);
1646:
1647: break;
1648:
1649: case 'L': /* insert a line */
1650:
1651: gotoxy(v, 0, cy);
1652:
1653: insert_line(v, cy);
1654:
1655: break;
1656:
1657: case 'M': /* delete line */
1658:
1659: gotoxy(v, 0, cy);
1660:
1661: delete_line(v, cy);
1662:
1663: break;
1664:
1665: case 'Y':
1666:
1667: state = escy_putch;
1668:
1669: return; /* YES, this should be 'return' */
1670:
1671:
1672:
1673: case 'b':
1674:
1675: state = setfgcol;
1676:
1677: return;
1678:
1679: case 'c':
1680:
1681: state = setbgcol;
1682:
1683: return;
1684:
1685: case 'd': /* clear to cursor position */
1686:
1687: curs_off(v);
1688:
1689: clrfrom(v, 0, 0, cx, cy);
1690:
1691: break;
1692:
1693: case 'e': /* enable cursor */
1694:
1695: curs_off(v);
1696:
1697: v->flags |= CURS_ON;
1698:
1699: v->hidecnt = 1; /* so --v->hidecnt shows the cursor */
1700:
1701: break;
1702:
1703: case 'f': /* cursor off */
1704:
1705: curs_off(v);
1706:
1707: v->hidecnt++;
1708:
1709: v->flags &= ~CURS_ON;
1710:
1711: break;
1712:
1713: case 'j': /* save cursor position */
1714:
1715: v->savex = v->cx;
1716:
1717: v->savey = v->cy;
1718:
1719: break;
1720:
1721: case 'k': /* restore saved position */
1722:
1723: gotoxy(v, v->savex, v->savey);
1724:
1725: break;
1726:
1727: case 'l': /* clear line */
1728:
1729: gotoxy(v, 0, cy);
1730:
1731: clrline(v, cy);
1732:
1733: break;
1734:
1735: case 'o': /* clear from start of line to cursor */
1736:
1737: curs_off(v);
1738:
1739: clrfrom(v, 0, cy, cx, cy);
1740:
1741: break;
1742:
1743: case 'p': /* reverse video on */
1744:
1745: v->flags |= FINVERSE;
1746:
1747: break;
1748:
1749: case 'q': /* reverse video off */
1750:
1751: v->flags &= ~FINVERSE;
1752:
1753: break;
1754:
1755: case 'v': /* wrap on */
1756:
1757: v->flags |= FWRAP;
1758:
1759: break;
1760:
1761: case 'w':
1762:
1763: v->flags &= ~FWRAP;
1764:
1765: break;
1766:
1767: }
1768:
1769: state = normal_putch;
1770:
1771: }
1772:
1773:
1774:
1775: /*
1776:
1777: * escy1_putch(v, c): for when an ESC Y + char has been seen
1778:
1779: */
1780:
1781: static void
1782:
1783: escy1_putch(v, c)
1784:
1785: SCREEN *v;
1786:
1787: int c;
1788:
1789: {
1790:
1791: gotoxy(v, c - ' ', escy1 - ' ');
1792:
1793: state = normal_putch;
1794:
1795: }
1796:
1797:
1798:
1799: /*
1800:
1801: * escy_putch(v, c): for when an ESC Y has been seen
1802:
1803: */
1804:
1805: static void
1806:
1807: escy_putch(v, c)
1808:
1809: SCREEN *v;
1810:
1811: int c;
1812:
1813: {
1814:
1815: escy1 = c;
1816:
1817: state = escy1_putch;
1818:
1819: }
1820:
1821:
1822:
1823: /*
1824:
1825: * normal_putch(v, c): put character 'c' on screen 'v'. This is the default
1826:
1827: * for when no escape, etc. is active
1828:
1829: */
1830:
1831:
1832:
1833: static void
1834:
1835: normal_putch(v, c)
1836:
1837: SCREEN *v;
1838:
1839: int c;
1840:
1841: {
1842:
1843: /* control characters */
1844:
1845: if (c < ' ') {
1846:
1847: switch (c) {
1848:
1849: case '\r':
1850:
1851: gotoxy(v, 0, v->cy);
1852:
1853: return;
1854:
1855: case '\n':
1856:
1857: if (v->cy == v->maxy) {
1858:
1859: curs_off(v);
1860:
1861: scroll(v);
1862:
1863: }
1864:
1865: else
1866:
1867: gotoxy(v, v->cx, v->cy+1);
1868:
1869: return;
1870:
1871: case '\b':
1872:
1873: gotoxy(v, v->cx-1, v->cy);
1874:
1875: return;
1876:
1877: case '\007': /* BELL */
1878:
1879: (void)bconout(CONDEV, 7);
1880:
1881: return;
1882:
1883: case '\033': /* ESC */
1884:
1885: state = putesc;
1886:
1887: return;
1888:
1889: case '\t':
1890:
1891: gotoxy(v, (v->cx + 8) & ~7, v->cy);
1892:
1893: return;
1894:
1895: default:
1896:
1897: return;
1898:
1899: }
1900:
1901: }
1902:
1903:
1904:
1905: (*vpaint)(v, c, v->cursaddr);
1906:
1907: v->flags &= ~CURS_FSTATE; /* we just erased the cursor */
1908:
1909: v->cx++;
1910:
1911: if (v->cx > v->maxx) {
1912:
1913: if (v->flags & FWRAP) {
1914:
1915: v->cx = 0;
1916:
1917: normal_putch(v, '\n');
1918:
1919: v->cursaddr = PLACE(v, v->cx, v->cy);
1920:
1921: } else {
1922:
1923: v->cx = v->maxx;
1924:
1925: }
1926:
1927: } else {
1928:
1929: #if 0
1930:
1931: v->cursaddr = PLACE(v, v->cx, v->cy);
1932:
1933: #else
1934:
1935: v->cursaddr++;
1936:
1937: if ( (v->cx & 1) == 0 && v->planes > 1) { /* new word */
1938:
1939: short skipwords = v->planes - 1;
1940:
1941: v->cursaddr += skipwords+skipwords;
1942:
1943: }
1944:
1945: #endif
1946:
1947: }
1948:
1949: }
1950:
1951:
1952:
1953: INLINE static void
1954:
1955: put_ch(v, c)
1956:
1957: SCREEN *v;
1958:
1959: int c;
1960:
1961: {
1962:
1963: (*state)(v, c & 0x00ff);
1964:
1965: }
1966:
1967:
1968:
1969: static long screen_open P_((FILEPTR *f));
1970:
1971: static long screen_read P_((FILEPTR *f, char *buf, long nbytes));
1972:
1973: static long screen_write P_((FILEPTR *f, const char *buf, long nbytes));
1974:
1975: static long screen_lseek P_((FILEPTR *f, long where, int whence));
1976:
1977: static long screen_ioctl P_((FILEPTR *f, int mode, void *buf));
1978:
1979: static long screen_close P_((FILEPTR *f, int pid));
1980:
1981: static long screen_select P_((FILEPTR *f, long p, int mode));
1982:
1983: static void screen_unselect P_((FILEPTR *f, long p, int mode));
1984:
1985:
1986:
1987: extern long null_datime P_((FILEPTR *f, short *time, int rwflag));
1988:
1989:
1990:
1991: DEVDRV screen_device = {
1992:
1993: screen_open, screen_write, screen_read, screen_lseek, screen_ioctl,
1994:
1995: null_datime, screen_close, screen_select, screen_unselect
1996:
1997: };
1998:
1999:
2000:
2001: static long
2002:
2003: screen_open(f)
2004:
2005: FILEPTR *f;
2006:
2007: {
2008:
2009:
2010:
2011: if (!current) {
2012:
2013: init();
2014:
2015: } else
2016:
2017: return EACCDN; /* screen in use */
2018:
2019:
2020:
2021: f->flags |= O_TTY;
2022:
2023: return 0;
2024:
2025: }
2026:
2027:
2028:
2029: static long
2030:
2031: screen_close(f, pid)
2032:
2033: FILEPTR *f;
2034:
2035: int pid;
2036:
2037: {
2038:
2039: if (f->links <= 0) {
2040:
2041: if (hardbase) {
2042:
2043: quickmove(oldbase, base, scrnsize);
2044:
2045: base = oldbase;
2046:
2047: Setscreen(oldbase, oldbase, -1);
2048:
2049: }
2050:
2051: current = 0;
2052:
2053: }
2054:
2055: return 0;
2056:
2057: }
2058:
2059:
2060:
2061: static long
2062:
2063: screen_write(f, buf, bytes)
2064:
2065: FILEPTR *f; const char *buf; long bytes;
2066:
2067: {
2068:
2069: SCREEN *v = current;
2070:
2071: long *r;
2072:
2073: long ret = 0;
2074:
2075: int c;
2076:
2077:
2078:
2079: (void)checkkeys();
2080:
2081: v->hidecnt++;
2082:
2083: v->flags |= CURS_UPD; /* for TOS 1.0 */
2084:
2085: r = (long *)buf;
2086:
2087: while (bytes > 0) {
2088:
2089: c = *r++;
2090:
2091: put_ch(v, c);
2092:
2093: bytes -= 4; ret+= 4;
2094:
2095: }
2096:
2097: --v->hidecnt;
2098:
2099: v->flags &= ~CURS_UPD;
2100:
2101: curs_on(v);
2102:
2103: return ret;
2104:
2105: }
2106:
2107:
2108:
2109: static long
2110:
2111: screen_read(f, buf, bytes)
2112:
2113: FILEPTR *f; char *buf; long bytes;
2114:
2115: {
2116:
2117: long *r, ret = 0;
2118:
2119:
2120:
2121: r = (long *)buf;
2122:
2123:
2124:
2125: while (bytes > 0) {
2126:
2127: if ( (f->flags & O_NDELAY) && !bconstat(CONDEV) )
2128:
2129: break;
2130:
2131: *r++ = bconin(CONDEV) & 0x7fffffff;
2132:
2133: bytes -= 4; ret += 4;
2134:
2135: }
2136:
2137: return ret;
2138:
2139: }
2140:
2141:
2142:
2143: static long
2144:
2145: screen_lseek(f, where, whence)
2146:
2147: FILEPTR *f;
2148:
2149: long where;
2150:
2151: int whence;
2152:
2153: {
2154:
2155: /* terminals always are at position 0 */
2156:
2157: return 0;
2158:
2159: }
2160:
2161:
2162:
2163: static long
2164:
2165: screen_ioctl(f, mode, buf)
2166:
2167: FILEPTR *f; int mode; void *buf;
2168:
2169: {
2170:
2171: long *r = (long *)buf;
2172:
2173: struct winsize *w;
2174:
2175:
2176:
2177: if (mode == FIONREAD) {
2178:
2179: if (bconstat(CONDEV))
2180:
2181: *r = 1;
2182:
2183: else
2184:
2185: *r = 0;
2186:
2187: }
2188:
2189: else if (mode == FIONWRITE) {
2190:
2191: *r = 1;
2192:
2193: }
2194:
2195: else if (mode == TIOCFLUSH) {
2196:
2197: /* BUG: this should flush the input/output buffers */
2198:
2199: return 0;
2200:
2201: }
2202:
2203: else if (mode == TIOCGWINSZ) {
2204:
2205: w = (struct winsize *)buf;
2206:
2207: w->ws_row = current->maxy+1;
2208:
2209: w->ws_col = current->maxx+1;
2210:
2211: }
2212:
2213: else
2214:
2215: return tty_ioctl(f, mode, buf);
2216:
2217:
2218:
2219: return 0;
2220:
2221: }
2222:
2223:
2224:
2225: static long
2226:
2227: screen_select(f, p, mode)
2228:
2229: FILEPTR *f; long p; int mode;
2230:
2231: {
2232:
2233: struct tty *tty = (struct tty *)f->devinfo;
2234:
2235: int dev = CONDEV;
2236:
2237:
2238:
2239: if (mode == O_RDONLY) {
2240:
2241: if (bconstat(dev)) {
2242:
2243: return 1;
2244:
2245: }
2246:
2247: if (tty) {
2248:
2249: /* avoid collisions with other processes */
2250:
2251: if (!tty->rsel)
2252:
2253: tty->rsel = p;
2254:
2255: }
2256:
2257: return 0;
2258:
2259: } else if (mode == O_WRONLY) {
2260:
2261: return 1;
2262:
2263: }
2264:
2265: /* default -- we don't know this mode, return 0 */
2266:
2267: return 0;
2268:
2269: }
2270:
2271:
2272:
2273: static void
2274:
2275: screen_unselect(f, p, mode)
2276:
2277: FILEPTR *f;
2278:
2279: long p;
2280:
2281: int mode;
2282:
2283: {
2284:
2285: struct tty *tty = (struct tty *)f->devinfo;
2286:
2287:
2288:
2289: if (tty) {
2290:
2291: if (mode == O_RDONLY && tty->rsel == p)
2292:
2293: tty->rsel = 0;
2294:
2295: else if (mode == O_WRONLY && tty->wsel == p)
2296:
2297: tty->wsel = 0;
2298:
2299: }
2300:
2301: }
2302:
2303:
2304:
2305: #endif /* FASTTEXT */
2306:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.